Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to specialize a template on language linkage?

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?

like image 424
Jared Hoberock Avatar asked Oct 12 '12 23:10

Jared Hoberock


People also ask

What is a template specialization?

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.

What is the specialty of a template function give example?

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.

Why do we need template specialization?

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).

Are template specializations inline?

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.


1 Answers

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).

like image 126
Jesse Good Avatar answered Nov 09 '22 12:11

Jesse Good