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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> специализация ф-ции для function<void()> 
V
    Опции темы
borisbn
Дата 28.2.2012, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Здравствуйте.
Следующий код
Код

#include <functional>
#include <iostream>

template< class Arg >
void foo( std::function< void(Arg) > f ) {
    std::cout << "foo< Arg >" << std::endl;
}

template<>
void foo< void >( std::function< void(void) > f ) {
    std::cout << "foo< void >" << std::endl;
}

//template<>
//void foo< float >( std::function< void(float) > f ) {
//    std::cout << "foo< float >" << std::endl;
//}

void i_func( int ) {}
void v_func() {}
void f_func( float ) {}

int main()
{
    std::function< void(int) > i_f( i_func );
    foo( i_f );
    std::function< void() > v_f( v_func );
    foo( v_f );
//    std::function< void( float ) > f_f( f_func );
//    foo( f_f );
}

http://liveworkspace.org/code/3b891bff696e...89efd162fb93933
выдаёт ошибку
Цитата

error: template-id 'foo<void>' for 'void foo(std::function<void()>)' does not match any template declaration
error: no matching function for call to 'foo(std::function<void()>&)'
note: candidate is:
note: template<class Arg> void foo(std::function<void(Arg)>)

Причём, если закомментировать все "void"-функции и раскомментировать "float", то всё работает.
Не могу понять, это какой-то глюк или всё так и должно быть ?
Как обойти это - я уже нашёл (SFINAE = enable_if + is_void), но хотелось бы понять, в чём здесь дело.
Спасибо.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 28.2.2012, 11:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  28.2.2012,  11:32 Найти цитируемый пост)
Не могу понять, это какой-то глюк или всё так и должно быть ?

Все же void(T) и void(void) это немного разные вещи, void(void) - это тот же void() и компилятор не может найти шаблонную функцию.

Почему бы не сделать вот так?
http://liveworkspace.org/code/aed04e13fed1...0d5547b7322db45
или можно через перегрузку
http://liveworkspace.org/code/0a23eab68ffd...dce71a6127f0cad



Это сообщение отредактировал(а) azesmcar - 28.2.2012, 11:54
PM   Вверх
boostcoder
Дата 28.2.2012, 12:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



все равно не понимаю, почему не работает вариант borisbn`а...

Это сообщение отредактировал(а) boostcoder - 28.2.2012, 12:05
PM WWW   Вверх
boostcoder
Дата 28.2.2012, 12:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



ааа, въехал! smile 
ну да, <void> и <void(void)> это же разные типы)

PM WWW   Вверх
borisbn
Дата 28.2.2012, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



azesmcar, спасибо. Первый вариант мне не подходит, т.к. в первую функцию можно подать функцию, принимающую два аргумента или возвращающую не void, а вот второй - то, что надо. Как-то я не сообразил, что специализация, с одной стороны - это та же перегрузка, но с другой стороны налагает некоторые ограничения.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
borisbn
Дата 28.2.2012, 14:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(boostcoder @  28.2.2012,  12:15 Найти цитируемый пост)
ну да, <void> и <void(void)> это же разные типы)

неа. у меня там не void и void(void), а void( T ) и void().
мдаааа. а вот такая специализация работает:
Код

template< class Res >
void foo( std::function< Res() > f ) {
    cout << "foo< Arg >" << endl;
}

template<>
void foo< void >( std::function< void() > f ) {
    cout << "foo< void >" << endl;
}

int i_func() {}
void v_func() {}

int main()
{
    std::function< int() > i_f( i_func );
    foo( i_f );
    std::function< void() > v_f( v_func );
    foo( v_f );
}

http://liveworkspace.org/code/296038cd2a53...57b051b93d6fb7a
хотя, на первый взгляд, это - вещи похожие


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 28.2.2012, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  28.2.2012,  14:24 Найти цитируемый пост)
неа. у меня там не void и void(void), а void( T ) и void().

void() и void(T), это разные вещи.

Цитата(borisbn @  28.2.2012,  14:24 Найти цитируемый пост)
мдаааа. а вот такая специализация работает:

все верно, возвращяемый тип частью сигнатуры функции не является. smile 
PM   Вверх
borisbn
Дата 28.2.2012, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



Цитата(azesmcar @  28.2.2012,  14:31 Найти цитируемый пост)
возвращяемый тип частью сигнатуры функции не является.

не знал... так по этому нельзя перегружать функции, если они отличаются только возвращаемым значением...

и всё равно остаётся непонятным - чем принципиально следующий код отличается от первого?
Код

template< class T >
struct S { T x; };

template< class T >
void foo( std::vector< S< T > > ) {
    cout << "foo( std::vector< S< T > > )" << endl;
}

template<>
void foo<float>( std::vector< S< float > > ) {
    cout << "foo( std::vector< S< float > > )" << endl;
}

std::vector< S< int > > i_v;
std::vector< S< float > > f_v;

int main() {
    foo( i_v );
    foo( f_v );
}

http://liveworkspace.org/code/bc1be32edad9...1518a7d69366a42
будем считать, что std::vector в данном примере - это std::function в первом...


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 28.2.2012, 15:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



borisbn

Вот пример попроще.
Код

#include <iostream>
#include <vector>

template <class T> void foo(void(*)(T)) {}
template <> void foo(void(*)(void)) {}

int main()
{
}

компилятор пытается найти функцию foo с таким параметром, но не находит.

Это сообщение отредактировал(а) azesmcar - 28.2.2012, 15:06
PM   Вверх
boostcoder
Дата 28.2.2012, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(azesmcar @  28.2.2012,  14:31 Найти цитируемый пост)
возвращяемый тип частью сигнатуры функции не является.

кстати да, вспомнил про обсуждение на некотором форуме.
Цитата

В случае обычной функции (не являющейся специализацией шаблона) — не является. Определение понятия "сигнатура функции" дано в C++11 — 1.3.17:
Цитата

signature
<function> name, parameter type list (8.3.5), and enclosing namespace (if any)

Сигнатура функции и тип функции — не одно и то же (эти два понятия часто путают).

PM WWW   Вверх
borisbn
Дата 28.2.2012, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 22
Всего: 135



кажется начинаю понимать: если в параметрах функции указано энное количество аргументов (пусть и шаблонных), то все специализации обязаны поддержать эту сигнатуру, а void - это не такой же тип, как и все остальные, а отсутствие параметра.
Вот пример ещё проще
Код

template< class T >
void foo( T ) { cout << "foo( T )" << endl; }

template<>
void foo<void>( void ) { cout << "foo()" << endl; }

int main() {
    foo( 42 );
    foo();
}

http://liveworkspace.org/code/d632e6c8ba6b...75ff271d1374f59


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 28.2.2012, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  28.2.2012,  15:39 Найти цитируемый пост)
void - это не такой же тип, как и все остальные, а отсутствие параметра

 smile 
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1207 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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