2012-10-12 72 views
8

甲功能的語言連接是其類型的一部分:是否可以在語言鏈接上專門化模板?

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

所有功能類型的默認語言聯動,函數名,變量和名稱是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; 
} 

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’ 

有SFINAE的一些應用程序,可以實現這個功能呢?

回答

7

是的,我相信你應該能夠根據C++標準專門化基於語言鏈接的模板。我測試了下面的代碼與Comeau compiler online並沒有錯誤編譯:

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

不過,我相信due to a gcc bug,基於語言聯動GCC不區分功能類型,所以這是不可能用gcc(和它似乎並不確定他們何時會解決這個問題)。

+1

您是否有一個說法引用說,鏈接是C++模板基於的類型信息的一部分? –

+4

@NicolBolas:不,我不知道。但是,我認爲問題中的引用是明確的:「具有不同語言鏈接的兩種函數類型是不同類型的。並且從[14.4類型等價]:'如果兩個模板-id的對應類型模板參數是相同類型',則它們指向相同的類或函數。 –

+1

@NicolBolas:在問題中會引用7.5.1 ... –