A function's language linkage is part of its type:
7.5.1 [dcl.link] of the ISO C++ standard:
The default language linkage of all function types, function names, and variable names is C++ language linkage. Two function types with different language linkages are distinct types even if they are otherwise identical.
Is it possible to specialize a template on the type of a function pointer's linkage, or otherwise introspect the type of a function pointer to determine its linkage 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 some application of SFINAE that could implement this functionality?
The act of creating a new definition of a function, class, or member of a class from a template declaration and one or more template arguments is called template instantiation. The definition created from a template instantiation is called a specialization.
Template in C++is a feature. We write code once and use it for any data type including user defined data types. For example, sort() can be written and used to sort any data type items. A class stack can be created that can be used as a stack of any data type.
Overloading it by either a different function template or a non-template function is arguably superior because its handling is more intuitive and it's overall more powerful (effectively by overloading the template, you have a partial specialization of the template, even though technically it's called partial ordering).
An explicit specialization of a function template is inline only if it is declared with the inline specifier (or defined as deleted), it doesn't matter if the primary template is inline.
Yes, I believe that you should be able to specialize a template based on its language linkage according to the C++ standard. I tested the following code with the Comeau compiler online and it compiled with no 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 bug, gcc does not distinguish function types based on language linkage, so this is not possible with gcc (and it doesn't seem sure when they will fix this).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With