Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> (g++)указатель на шаблонную функцию 
V
    Опции темы
GoldFinch
Дата 27.11.2010, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Код

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}

template<class T>
void method_to_fn(T* that)
{
    that->bar();
}

#include <iostream>

struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};

int main()
{
    //function_with_callback((callback_t)method_to_fn<Foo>, NULL);
    function_with_callback((callback_t)static_cast<void(*)(Foo*)>(method_to_fn<Foo>), NULL);
}

этот код работает.
а если раскомментировать 22ю строчку, то он будет работать в MSVC, а g++ выдаст ошибку 
Код

 error: insufficient contextual information to determine type

link1, link2
при этом на самом деле причина ошибки в том, что g++ считает method_to_fn перегруженной функцией, и по этому нужен static_cast чтобы выбрать "перегрузку".

почему так?
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 15:26 (ссылка) |  (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:20 Найти цитируемый пост)
Код
(callback_t)static_cast<void(*)(Foo*)>(method_to_fn<Foo>)
Красотища...
Чистой воды UB.


Это сообщение отредактировал(а) Леопольд - 27.11.2010, 15:38


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
boostcoder
Дата 27.11.2010, 15:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(GoldFinch @  27.11.2010,  15:20 Найти цитируемый пост)
g++ выдаст ошибку 

хз о чем Вы...
http://liveworkspace.org/code/f7dde36deec8...4dc382d0b33ea77
PM WWW   Вверх
GoldFinch
Дата 27.11.2010, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



boostcoder, какая там версия гцц?
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



GoldFinch, пока ещё не смог понять из кода, что именно надо...


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, не страшно

boostcoder, похоже действительно в 4.5 это починили, это какая-то особенность С++0х 
PM MAIL ICQ   Вверх
boostcoder
Дата 27.11.2010, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


Профиль
Группа: Завсегдатай
Сообщений: 5458
Регистрация: 1.4.2010

Репутация: 49
Всего: 110



Цитата(GoldFinch @  27.11.2010,  15:35 Найти цитируемый пост)
какая там версия гцц? 

4.5.1
PM WWW   Вверх
Леопольд
Дата 27.11.2010, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:38 Найти цитируемый пост)
Леопольд, не страшно
Может это?
Код
template<typename T>
void function_with_callback(void(*callback)(T*), T * param)
{
    callback(param);
}

template<class T>
void method_to_fn(T* that)
{
    that->bar();
}

#include <iostream>

struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};

void foo(char const* str)
{
   std::cout << str << '\n';
}

int main()
{
    Foo inst;
    function_with_callback(method_to_fn<Foo>, &inst);
    function_with_callback(foo, "hello!");
}
http://liveworkspace.org/code/a442dfbbd883cfe0d08df7c6a98cd0db


Это сообщение отредактировал(а) Леопольд - 27.11.2010, 15:47


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, не угадали.
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 15:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:44 Найти цитируемый пост)
Леопольд, не угадали. 
Тогда, может объясните по человечески? Потому что, если избавиться от UB, получается именно это...



--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 15:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Цитата(boostcoder @ 27.11.2010,  16:32)
Цитата(GoldFinch @  27.11.2010,  15:20 Найти цитируемый пост)
g++ выдаст ошибку 

хз о чем Вы...
http://liveworkspace.org/code/f7dde36deec8...4dc382d0b33ea77

эээ нееет) это чит smile
потому что когда там обе строчки, версия со статик-кастом позволяет работать версии без статик-каста
Код

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
template<class T>
void method_to_fn(T* that)
{
    that->bar();
}

#define CODE_VARIANT 1

#include <iostream>
struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};
int main()
{
#if CODE_VARIANT == 1
    function_with_callback((callback_t)method_to_fn<Foo>, NULL);
#else
    function_with_callback((callback_t)static_cast<void(*)(Foo*)>(method_to_fn<Foo>), NULL);
#endif
}


http://liveworkspace.org/code/9b7c03115be3...2fc50ee142cd60e

Добавлено через 2 минуты и 8 секунд
Леопольд, this тут вообще ни при чем, а нулевой this - это вроде не UB.
В любом случае, это к проблеме отношения не имеет, добавляйте туда объект если хотите.

Добавлено через 4 минуты и 8 секунд
btw, liveworkspace.org всем хорош, только там табуляция 3 символа =\ хотелось бы 4 %)
PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  15:51 Найти цитируемый пост)
Леопольд, this тут вообще ни при чем, а нулевой this - это вроде не UB.
Показалось... Там ведь не разыменовывается указатель.

UB приводить указатели на функцию, static_cast неспроста не даёт этого делать.
Это UB в действии http://liveworkspace.org/code/9b7c03115be3...2fc50ee142cd60e

Использовать С-ишное приведение в С++, зачем?
Код
#include <cstdlib>

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}

template<class T>
void method_to_fn(void * param)
{
    static_cast<T*>(param)->bar();
}

#define CODE_VARIANT 2

#include <iostream>
struct Foo
{
    void bar() { std::cout << "Foo::bar OK\n"; }
};
int main()
{
    function_with_callback(method_to_fn<Foo>, NULL);
}

Наверное, это ближе всех:
http://liveworkspace.org/code/c631f5ef9be4...477373840e60b9a
static_cast из void * , тоже самое что и reinterpret_cast. Только выглядит безобиднее.

На мой взгляд, не особо много смысла. Зачем это надо?

Это сообщение отредактировал(а) Леопольд - 27.11.2010, 16:34


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, С-style cast тоже ни при чем. Что вы, приведения типов функций никогда чтоле не видели %)

PM MAIL ICQ   Вверх
Леопольд
Дата 27.11.2010, 16:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 943
Регистрация: 17.6.2009

Репутация: 10
Всего: 13



Цитата(GoldFinch @  27.11.2010,  16:21 Найти цитируемый пост)
Что вы, приведения типов функций никогда чтоле не видели
В С++ не видел. Про С не могу сказать, может там это легально.

Это сообщение отредактировал(а) Леопольд - 27.11.2010, 16:24


--------------------
вопросов больше чем ответов
PM MAIL   Вверх
GoldFinch
Дата 27.11.2010, 16:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Завсегдатай
Сообщений: 2141
Регистрация: 30.11.2008

Репутация: 15
Всего: 26



Леопольд, впрочем, спасибо за подсказку

убрал из сигнатуры method_to_fn шаблонный тип, "перегрузки" исчезли, и всё заработало

Код

typedef void(*callback_t)(void*);
void function_with_callback(callback_t callback, void* param)
{
    callback(param);
}
template<class T>
void method_to_fn(void* that)
{
    static_cast<T*>(that)->bar();
}

#include <iostream>
struct Foo
{
    void bar() { std::cout << "test OK\n"; }
};
int main()
{
    function_with_callback(method_to_fn<Foo>, NULL);
}


PM MAIL ICQ   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0735 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.