2010-11-16 61 views
0

我在stackoverflow上發現了一些非常有趣的C++代碼,我對此非常困惑,因爲作者說它應該可以工作,並且它在我的gcc 4.5.1和4.4 目的是檢查是否含有類或不特定的方法檢查C++中是否存在函數時出現問題

代碼:

#include <iostream> 

struct Hello 
{ 
    int helloworld() 
    { return 0; } 
}; 

struct Generic {}; 


// SFINAE test 
template <typename T> 
class has_helloworld 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(typeof(&C::helloworld)) ; 
    template <typename C> static two test(...); 


public: 
    enum { value = sizeof(test<T>(0)) == sizeof(char) }; 
}; 


int 
main(int argc, char *argv[]) 
{ 
    std::cout << has_helloworld<Hello>::value << std::endl; 
    std::cout << has_helloworld<Generic>::value << std::endl; 
    return 0; 
} 

我有編譯器錯誤:

ISO C++ forbids in-class initialization of non-const static member 'test'

其他一些評論說 - 我可以改變 '的typeof(&Ç:: HelloWorld的)' 到 '的char [的sizeof(&Ç:: HelloWorld的)' 但後來我的輸出是

1 
1 

什麼是錯的,因爲只有一個類具有helloworld功能

是否有任何方法使其工作? 此外,我會非常心存感激,如果有人可以解釋是什麼讓這個命令:

test(char[sizeof(&C::helloworld)]) ; 

非常感謝你:)

+3

你鏈接到我的答案,但我的答案不包含'typeof'事情。 – 2010-11-16 23:46:54

+1

一,我很驚訝,這給你一個關於'test'是一個非const成員的錯誤 - 這兩個測試實例看起來像函數聲明。二,這不是反思。反射意味着類型,方法,成員等的運行時發現;這一切都是在編譯時靜態完成的。 – 2010-11-17 01:27:04

回答

2

你的麻煩與使用的積分爲零,使用typeof。使用MSVC10,decltype和nullptr,對於此代碼來說,打印正確的值是一個微不足道的修改。

template <typename T> 
class has_helloworld 
{ 
    typedef char one; 
    typedef long two; 

    template <typename C> static one test(decltype(&C::helloworld)) ; 
    template <typename C> static two test(...); 


public: 
    enum { value = std::is_same<decltype(test<T>(nullptr)), char>::value }; 
}; 


int main(int argc, char *argv[]) 
{ 
    std::cout << has_helloworld<Hello>::value << std::endl; 
    std::cout << has_helloworld<Generic>::value << std::endl; 
    std::cin.get(); 
    return 0; 
} 

我不是typeof運算方面的專家,但這樣的事情應該是可行的:

struct no_type {}; 
// SFINAE test 
template <typename T> 
class has_helloworld 
{ 
    template <typename C> static typeof(&C::helloworld) test(C* i); 
    template <typename C> static no_type test(...); 


public: 
    enum { value = std::is_same<no_type, typeof(test<T>(0))>::value }; 
}; 
+0

非常感謝你! :) – 2010-11-20 16:16:50