Is it possible to specialize a template by language binding?

The binding of language functions is part of its type:

7.5.1 [dcl.link] of the ISO C ++ standard:

The default language association for all types of functions, function names, and variable names is the C ++ language association. Two types of functions with different language relationships are different types, even if they are identical to each other.

Is it possible to specialize a template by the type of binding of a pointer to a function or otherwise enter the type of a pointer to a function to determine its binding at compile time?

This first attempt does not seem legal:

#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 outputs:

 $ 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' 

Is there any SFINAE application that can implement this functionality?

+8
c ++ c ++ 11 sfinae linkage
source share
1 answer

Yes, I believe that you should be able to specialize a template based on its language binding in accordance with the C ++ standard. I checked the following code with the Comau compiler online and compiled without errors:

 #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; } 

However, I believe that due to a gcc error , gcc does not distinguish between types of functions based on language binding, therefore this is not possible with gcc (and this does not seem certain when they will fix it).

+7
source share

All Articles