8

関数の言語リンケージは、その型の一部です。

ISO C++ 標準の 7.5.1 [dcl.link]:

すべての関数型、関数名、および変数名のデフォルトの言語リンケージは、C++ 言語リンケージです。言語リンケージが異なる 2 つの関数型は、それ以外は同一であっても、別個の型です。

関数ポインターのリンケージの型に合わせてテンプレートを特殊化することは可能ですか? または、関数ポインターの型をイントロスペクトして、コンパイル時にそのリンケージを判別することはできますか?

この最初の試みは合法ではないようです。

#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 ‘&lt;type error>’)
test.cpp:32:10: error: two or more data types in declaration of ‘main’

この機能を実装できる SFINAE のアプリケーションはありますか?

4

1 に答える 1

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

ただし、gccのバグが原因で、gccは言語リンケージに基づいて関数型を区別しないため、gccではこれは不可能であると思います(そして、いつ修正されるかはわかりません)。

于 2012-10-13T01:03:10.110 に答える