2012-01-27 107 views
1

我有一個枚舉值作爲我想作爲模板參數傳遞的類的成員?編譯器抱怨該成員不能用於常量表達式中。這項工作有什麼神奇嗎?有沒有辦法從變量設置模板參數?

我目前的解決方案是switch-case聲明,但在我的原始代碼EType有近200條目。所以我最初的想法是編寫一個type_traits將枚舉值映射到類型。

這裏是我的問題的一個實例(也ideone.com)(問題是main()最後一行):

#include <iostream> 

enum EType 
{ 
    eType_A, 
    eType_B, 
    eType_C 
}; 

struct Foo 
{ 
    Foo(EType eType) 
     : m_eType(eType) 
    { 
    } 

    EType m_eType; 
}; 

template <EType eType> 
struct Bar 
{ 
    static std::string const toString() 
    { 
     return "-"; 
    } 
}; 

template <> 
struct Bar<eType_A> 
{ 
    static std::string const toString() 
    { 
     return "A"; 
    } 
}; 

template <> 
struct Bar<eType_B> 
{ 
    static std::string const toString() 
    { 
     return "B"; 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Bar<eType_A>::toString()=" << Bar<eType_A>::toString() << "\n"; 
    std::cout << "Bar<eType_B>::toString()=" << Bar<eType_B>::toString() << "\n"; 
    std::cout << "Bar<eType_C>::toString()=" << Bar<eType_C>::toString() << "\n"; 

    Foo stFooA(eType_A); 
    std::cout << "Bar<stFooA.m_eType>::toString()=" << Bar<stFooA.m_eType>::toString() << "\n"; // <--- here ist the problem 
} 

的例子產生這些錯誤:

prog.cpp: In function ‘int main(int, char**)’: 
prog.cpp:54: error: ‘stFooA’ cannot appear in a constant-expression 
prog.cpp:54: error: `.' cannot appear in a constant-expression 
prog.cpp:54: error: template argument 1 is invalid 

回答

5

您傳入的模板參數Bar 必須在編譯時知道。由於stFooA.m_eType在運行期間可能會更改,所以無法正常工作,因此會出現該錯誤。

要回答你的其他問題,是否有一些魔法讓這個工作?也許可能 - 你允許在編譯時知道m_eType的值嗎?如果這是你的問題的一個有效的約束,你可以把它改成這樣的事情,它會工作:

// ... 
template <EType eType> 
struct Foo 
{ 
    Foo() 
    { 
    } 

    static const EType m_eType = eType; 
}; 

int main(int argc, char *argv[]) 
{ 
    std::cout << "Bar<eType_A>::toString()=" << Bar<eType_A>::toString() << "\n"; 
    std::cout << "Bar<eType_B>::toString()=" << Bar<eType_B>::toString() << "\n"; 
    std::cout << "Bar<eType_C>::toString()=" << Bar<eType_C>::toString() << "\n"; 

    Foo<eType_A> stFooA; 
    std::cout << "Bar<stFooA.m_eType>::toString()=" 
       << Bar<Foo<eType_A>::m_eType>::toString() 
       << "\n"; // Foo<eType_A>::m_eType is known at compile-time so this works 
} 
+0

好一點,但也沒有辦法在編譯時使'm_eType'成爲已知的。 – Lars 2012-01-27 08:16:48

+0

@Lars在那種情況下,你別無選擇 - 模板可能不是正確的工具,你需要在運行時以某種方式解決它。也許把模板參數變成'toString'的常規函數​​參數? – greatwolf 2012-01-27 08:19:30

3

沒有,模板擴展在編譯時完成。只有在編譯程序時知道該值,它纔有效。

編譯器還要求提供一個常量表達式。

+0

我一直擔心它...打破按設計.. – Lars 2012-01-27 08:10:07

相關問題