2010-11-04 75 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

相关问题