2010-11-04 112 views
14

我有許多類/這樣的方法創建的字符串:取決於模板參數

template<typename CharT, typename TraitsT = std::char_traits<CharT> > 
struct Foo 
{ 
    std::basic_string<CharT, TraitsT> getFoo(void) const 
    { 
    return "Foo"; // + this->member_var1 + this->member_var2... 
    } 
}; 

但根據圖表,我必須使用「」 L「」 U「」或「U」 (對於char,wchar_t,u16char_t,u32char_t)。

必須使用什麼語法來創建與這些模板參數無關的字符串?

+1

好問題... – 2010-11-04 20:01:00

回答

7

你真的需要不同的文字嗎,或者你可以使用迭代器的構造函數嗎?

const char *f = "Foo"; 
return std::basic_string<CharT, TraitsT>(f, f + 3); 

如果您擔心未來可以輕鬆更改字面量,那麼可能會比「3」更強壯一些。

在響應到如此地步,這是不是很漂亮,怎麼樣:

然後,你必須:

return proper_string<CharT, TraitsT>("Foo"); 

如果你真的需要不同的文字,那麼唯一的事情我想到目前爲止是爲它創造特質,這就是確實是太可怕了:

template<typename T> struct FooString { 
}; 

template<> struct FooString<char> { 
    static const char *value() { return "Foo"; } 
}; 
template<> struct FooString<wchar_t> { 
    static const wchar_t *value() { return L"Foo"; } 
}; 
... etc ... 

return FooString<CharT>::value(); 
+1

使用字符數組而不是指向const char的指針,而是使用'sizeof f'。 – dreamlax 2010-11-04 20:03:45

+1

'const char f [] =「Foo」;返回std :: basic_string (f,f + sizeof f)' – dreamlax 2010-11-04 20:04:50

+0

從兩個迭代器創建是一種解決方法,但對許多此類情況不是一個很好的解決方案。 – cytrinox 2010-11-04 20:04:55

1

如果你打算無論如何要的東西附加到字符串,使用字符串流:

std::basic_string<CharT, TraitsT> getFoo(void) const 
{ 
    std::basic_ostringstream<CharT, TraitsT> os; 
    os << "Foo"; 
    // os << this->member_var1 << this->member_var2... 
    return os.str(); 
} 

我喜歡史蒂夫·傑索普的答案了。

1

下面是使用宏

template < typename CharT > 
struct char_t_literal_selector; 

template <> 
struct char_t_literal_selector<char> { 
    static const char *select(const char *s, const wchar_t *, const char16_t *, const char32_t *) 
    { 
     return s; 
    } 
}; 

template <> 
struct char_t_literal_selector<wchar_t> { 
    static const wchar_t *select(const char *, const wchar_t *s, const char16_t *, const char32_t *) 
    { 
     return s; 
    } 
}; 

template <> 
struct char_t_literal_selector<char16_t> { 
    static const char16_t *select(const char *, const wchar_t *, const char16_t *s, const char32_t *) 
    { 
     return s; 
    } 
}; 

template <> 
struct char_t_literal_selector<char32_t> { 
    static const char32_t *select(const char *, const wchar_t *, const char16_t *, const char32_t *s) 
    { 
     return s; 
    } 
}; 

#define CHART_LITERAL(str) (char_t_literal_selector<CharT>::select(str, L ## str, u ## str, U ## str)) 


template<typename CharT, typename TraitsT = std::char_traits<CharT> > 
struct Foo 
{ 
    std::basic_string<CharT, TraitsT> getFoo(void) const 
    { 
    return CHART_LITERAL("Foo"); // + this->member_var1 + this->member_var2... 
    } 
}; 

假設模板參數名稱始終CharT的解決方案。如果不是,則向宏添加另一個參數。 HTH

+0

這比我的解決方案獲得文字(我認爲)更好,但我不確定文字是否真的需要,或者只是'basic_string'。 – 2010-11-04 20:23:42

相關問題