2012-10-12 6 views
8

язык связь функция, является частью его типа:Можно ли специализировать шаблон по языковой привязке?

7.5.1 [dcl.link] из ISO C++ стандарт:

язык по умолчанию связь всех типов функций, имена функций и переменных имена - это ссылка на язык C++. Два типа функций с различными языковыми связями - это разные типы, даже если они идентичны друг другу.

Можно ли специализировать шаблон по типу ссылки на указатель функции или иначе ввести тип указателя функции для определения его привязки во время компиляции?

Это первая попытка не кажется законным:

#include <iostream> 
#include <typeinfo> 

struct cpp {}; 
struct c {}; 

extern "C++" void foo() 
{ 
    std::cout << "foo" << std::endl; 
} 

extern "C" void bar() 
{ 
    std::cout << "bar" << std::endl; 
} 

template<typename> struct linkage; 

template<> 
    struct linkage<void(*)()> 
{ 
    typedef cpp type; 
}; 

template<> 
    struct linkage<extern "C" void(*)()> 
{ 
    typedef c type; 
} 


int main() 
{ 
    std::cout << "linkage of foo: " << typeid(linkage<decltype(&foo)>::type).name() << std::endl; 
    std::cout << "linkage of bar: " << typeid(linkage<decltype(&bar)>::type).name() << std::endl; 
    return 0; 
} 

g++-4.6 выходы:

$ g++ -std=c++0x test.cpp 
test.cpp:26:38: error: template argument 1 is invalid 
test.cpp:26:3: error: new types may not be defined in a return type 
test.cpp:26:3: note: (perhaps a semicolon is missing after the definition of ‘<type error>’) 
test.cpp:32:10: error: two or more data types in declaration of ‘main’ 

Есть ли применение SFINAE, которые могли бы реализовать эту функцию?

ответ

7

Да, я считаю, что вы должны иметь возможность специализировать шаблон на основе его языковой привязки в соответствии со стандартом C++. Я тестировал следующий код с Comeau compiler online и компилируется без ошибок:

#include <iostream> 
#include <typeinfo> 

struct cpp {}; 
struct c {}; 

extern "C++" typedef void(*cppfunc)(); 
extern "C" typedef void(*cfunc)(); 

extern "C++" void foo() 
{ 
    std::cout << "foo" << std::endl; 
} 

extern "C" void bar() 
{ 
    std::cout << "bar" << std::endl; 
} 

template<typename> struct linkage; 

template<> 
    struct linkage<cppfunc> 
{ 
    typedef cpp type; 
}; 

template<> 
    struct linkage<cfunc> 
{ 
    typedef c type; 
}; 


int main() 
{ 
    std::cout << "linkage of foo: " << typeid(linkage<decltype(&foo)>::type).name() << std::endl; 
    std::cout << "linkage of bar: " << typeid(linkage<decltype(&bar)>::type).name() << std::endl; 
    return 0; 
} 

Однако, я считаю, что due to a gcc bug, НКУ не различает типы функций на основе языка связи, так что это не возможно с GCC (и не уверены, когда они это исправит).

+1

У вас есть спецификация, в которой говорится, что связь является частью информации о типе, на которой основаны шаблоны C++? –

+4

@ НиколБолас: Нет, не знаю. Тем не менее, я думаю, что цитата в вопросе понятна: «Два типа функций с разными языковыми связями - это разные типы». И из [14.4 Типовой эквивалентности]: 'Два идентификатора шаблона относятся к одному и тому же классу или функции, если их соответствующие шаблоны-аргументы типа одного типа '. –

+1

@NicolBolas: это будет 7.5.1, процитированное в вопросе ... –

 Смежные вопросы

  • Нет связанных вопросов^_^