是否可以在语言链接上专门化模板?

Jar*_*ock 8 c++ sfinae linkage c++11

函数的语言链接是其类型的一部分:

7.5.1 ISO C++标准的[dcl.link]:

所有函数类型,函数名和变量名的默认语言链接是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;
}
Run Code Online (Sandbox Code Playgroud)

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’
Run Code Online (Sandbox Code Playgroud)

是否有一些可以实现此功能的SFINAE应用程序?

Jes*_*ood 7

是的,我相信您应该能够根据C++标准基于其语言链接来专门化模板.我在线使用Comeau编译器测试了以下代码,编译时没有错误:

#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;
}
Run Code Online (Sandbox Code Playgroud)

但是,我认为由于gcc错误,gcc不区分基于语言链接的函数类型,所以gcc不可能这样做(并且它们似乎不确定何时会解决这个问题).

  • @NicolBolas:不,我没有.但是,我认为问题中的引用很清楚:"具有不同语言联系的两种函数类型是不同的类型".从[14.4类型等价]:`两个模板-id引用相同的类或函数,如果它们对应的类型模板参数是相同的类型`. (4认同)