2010-11-04 22 views
14

Tôi có nhiều lớp/phương pháp như thế này:Tạo chuỗi tùy thuộc vào đối số mẫu

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... 
    } 
}; 

Nhưng tùy thuộc vào biểu đồ, tôi phải sử dụng "", L "", u "" hoặc "U" (đối với char, wchar_t, u16char_t, u32char_t).

Cú pháp nào phải được sử dụng để tạo chuỗi được chỉ định từ các đối số mẫu như vậy?

+1

Câu hỏi hay ... –

Trả lời

7

Bạn có thực sự cần các chữ khác nhau hay bạn có thể sử dụng hàm tạo của trình lặp không?

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

Có lẽ với một cái gì đó nhiều hơn một chút mạnh mẽ hơn "3" trong đó, nếu bạn đang lo lắng về tính dễ thay đổi chữ trong tương lai.

Để đối phó với điểm rằng đây không phải là rất tốt đẹp, những gì về:

Sau đó, bạn có:

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

Nếu bạn thực sự cần sự theo nghĩa đen, sau đó điều duy nhất khác nhau Tôi đã nghĩ đến thời điểm này là tạo các đặc điểm cho nó, là thực sự khủng khiếp:

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

Sử dụng một mảng ký tự thay vì một con trỏ tới const char và sử dụng 'sizeof f' thay thế. – dreamlax

+1

'const char f [] =" Foo "; return std :: basic_string (f, f + sizeof f) ' – dreamlax

+0

Tạo từ hai trình lặp là giải pháp thay thế, nhưng không phải là giải pháp tốt cho nhiều tình huống như vậy. – cytrinox

1

Nếu bạn đang đi để được phụ thêm điều cần chuỗi dù sao đi nữa, sử dụng một stringstream:

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(); 
} 

Tôi thích câu trả lời Steve Jessop, quá.

1

Đây là một giải pháp sử dụng một MACRO

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... 
    } 
}; 

giả tên mẫu tham số luôn luôn là CharT. Nếu không, hãy thêm tham số khác vào macro. HTH

+0

Điều này là tốt hơn so với giải pháp của tôi để nhận được chữ (tôi nghĩ), nhưng tôi không chắc chắn nếu chữ là thực sự cần thiết, hoặc chỉ 'basic_string'. –

Các vấn đề liên quan