2012-10-12 14 views
8

एक समारोह की भाषा लिंकेज अपने प्रकार का हिस्सा है:क्या भाषा संबंध पर एक टेम्पलेट विशेषज्ञ करना संभव है?

सभी प्रकार के समारोह के डिफ़ॉल्ट भाषा के संबंध, समारोह के नाम, और चर:

7.5.1 [dcl.link] आईएसओ सी ++ मानक का नाम सी ++ भाषा संबंध है। अलग-अलग भाषा संबंधों के साथ दो फ़ंक्शन प्रकार अलग-अलग प्रकार होते हैं, भले ही वे अन्यथा समान हों।

क्या फ़ंक्शन पॉइंटर के लिंक के प्रकार पर टेम्पलेट का विशेषज्ञ होना संभव है, या अन्यथा संकलन समय पर इसके लिंक को निर्धारित करने के लिए फ़ंक्शन पॉइंटर के प्रकार का आत्मनिरीक्षण करना संभव है?

यह पहला प्रयास कानूनी प्रतीत नहीं होता:

#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

हां, मेरा मानना ​​है कि आप सी ++ मानक के अनुसार अपनी भाषा संबंध के आधार पर एक टेम्पलेट का विशेषज्ञ बनने में सक्षम होना चाहिए। मैं 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, जीसीसी भाषा लिंकेज के आधार पर समारोह प्रकार भेद नहीं करता है, तो यह जीसीसी साथ संभव नहीं है (और यह यह सुनिश्चित नहीं होता कि वे इसे कब ठीक करेंगे)।

+1

क्या आपके पास शायद एक विशिष्ट उद्धरण है जो कहता है कि लिंकेज उस प्रकार की जानकारी का हिस्सा है जो सी ++ टेम्पलेट्स पर आधारित है? –

+4

@ निकोलबोलस: नहीं, मैं नहीं करता हूं। हालांकि, मुझे लगता है कि प्रश्न में उद्धरण स्पष्ट है: 'विभिन्न भाषा संबंधों के साथ दो फ़ंक्शन प्रकार अलग-अलग प्रकार हैं'। और [14.4 प्रकार समतुल्यता] से: 'दो टेम्पलेट-आईडी एक ही वर्ग या फ़ंक्शन को संदर्भित करते हैं यदि उनके संबंधित प्रकार टेम्पलेट-तर्क समान प्रकार हैं। –

+1

@ निकोलबोलस: प्रश्न में 7.5.1 उद्धृत किया जाएगा ... –

संबंधित मुद्दे