模板string怎么初始化静态变量

miliggate 2013-03-22 07:32:52
template<class STR>
class str_c
{
typedef STR string;
static string _sBody;
};

template<class STR>
STR str_c<STR>::_sBody="name";但是这里有一个问题,如果STR是宽字符的时候
name就不能给_sBody,必须要变成L"name"才能赋值
有什么办法解决吗?
...全文
287 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
tofu_ 2013-03-23
  • 打赏
  • 举报
回复
嗯,关于traits和policy,大家比较一致的看法是:traits更侧重于类型,而policy侧重于行为。从这种定义上来看,我上面那个确实偏policy多一些。不过,一直以来标准库内的char_traits那种混合体都是被称为traits,所以我也就对这两个定义没有作太严格的区分,以后会更加注意的,多谢了。 从楼主提供的信息来看,我猜测他需要的是一个类似于字符串表的东西。那个str_c里面,应该是用于存储各种格式的字符串常/变量。因此才有了上面的设计。 你8#的代码,总有点设计过度的感觉。额,说得如此直接,如果说错了还请见谅。 首先是,你猜测楼主所说的静态变量的类型并不仅是字符串,所以你希望str_c里面能同时容纳各种不同的类型。但是现在你把str_traits定义为str_c第一个模板参数T到某个member_type的映射。因为针对一个指定的类型T,你只能得到唯一对应的member_type,所以同时支持多种类型并不成立,也就是说,s_body如果为string类型,那么s_body2肯定不能是其他类型。 另外,你的str_policy跟我7#的str_traits一样。我那个str_traits也没有限定参数类型一定要是const char*,定制Init的参数跟你是一样的。我猜是那个format的函数名干扰了你,让你觉得那就只是个操作字符串的函数。甚至str_c内部的静态变量个数也可以定制,这个我觉得最不需要说了。不管是哪种方案,都不可能也不会去限定静态变量的个数。我觉得你那一对str_traits和str_policy就是定义了一个参数列表 + 类型T1到类型T2的映射关系,把str_traits和str_policy分开没感觉到对可扩展性有什么明显的好处,反倒是代码更多,功能更分散。str_traits这样使用限制性太强。
飞天御剑流 2013-03-23
  • 打赏
  • 举报
回复
引用 10 楼 SisMVG 的回复:
引用 8 楼 supermegaboy 的回复:楼上写的是policy而不是trait。我们写个代码除了考虑眼前,更要考虑以后如何便于扩展、便于维护,更何况楼主说了还有N多的静态变量(这些静态变量并不都是字符吧?楼主没有说,但按语义我猜是这样吧?),3楼的代码属于侵入式设计,日后若需求有变化,改动的就将是str_c类体;而trait和policy是非侵入式的,可以为str……
这样的话,就不需要在MPL中找了。 只需要像3楼那样对wchar_t或者wstring做一个特化,但是,不需要特化整个str_c,仅对静态成员特化就行。
飞天御剑流 2013-03-23
  • 打赏
  • 举报
回复
额,这么快就结了帖哇。
引用 9 楼 tofu_ 的回复:
嗯,关于traits和policy,大家比较一致的看法是:traits更侧重于类型,而policy侧重于行为。从这种定义上来看,我上面那个确实偏policy多一些。不过,一直以来标准库内的char_traits那种混合体都是被称为traits,所以我也就对这两个定义没有作太严格的区分,以后会更加注意的,多谢了。 从楼主提供的信息来看,我猜测他需要的是一个类似于字符串……
trait和policy本来就差别极小,不作严格区分亦未尝不可。 是否过度设计,要看需求了,trait和policy在这里可以提供一种颇具灵活性和扩展性的解决方案。也许是偶词不达意,我的本意并非满足各种各样的类型(倒成了副作用了),而是: 1、满足不同底层实现的需求; 2、对于某些不希望特例化的类型,可以提供无缝转换; 3、非侵入式的灵活扩展。 此外,定制的意思并不是要“限定”些什么,刚好相反,而是满足不同情况下静态变量的数量可能不同的需求。
miliggate 2013-03-23
  • 打赏
  • 举报
回复
引用 8 楼 supermegaboy 的回复:
楼上写的是policy而不是trait。我们写个代码除了考虑眼前,更要考虑以后如何便于扩展、便于维护,更何况楼主说了还有N多的静态变量(这些静态变量并不都是字符吧?楼主没有说,但按语义我猜是这样吧?),3楼的代码属于侵入式设计,日后若需求有变化,改动的就将是str_c类体;而trait和policy是非侵入式的,可以为str_c增加很大的灵活性,日后的扩展,增加trait……
很不幸。。全部都是字符串问题 其实我只是定义了一堆静态字符串,然后想要不用手动特化代码, 方便的使STR 不论在string,还是wstring得情况下都可以运作。。 而且我的STR只准备在string还有wstring的情况下运作 我还是去看看mpl里有没有这样的东西吧..
飞天御剑流 2013-03-23
  • 打赏
  • 举报
回复
楼上写的是policy而不是trait。我们写个代码除了考虑眼前,更要考虑以后如何便于扩展、便于维护,更何况楼主说了还有N多的静态变量(这些静态变量并不都是字符吧?楼主没有说,但按语义我猜是这样吧?),3楼的代码属于侵入式设计,日后若需求有变化,改动的就将是str_c类体;而trait和policy是非侵入式的,可以为str_c增加很大的灵活性,日后的扩展,增加trait和policy的特化就行了。 楼上的代码可以改为如下这样: 偶没有使用string或wstring,因为从楼主写了typedef STR string来看,似乎并没有使用string的意思,不知道有没有理解错误。

template< typename T >
struct str_traits;

template< >
struct str_traits< const char* >
{
    typedef T1 type;  //T1的类型视需求而定
};

template< >
struct str_traits< const wchar_t* >
{
    typedef T2 type;  //T2的类型视需求而定
};

............

template< >
struct str_traits< other type >
{
    typedef Tn type;  //Tn的类型视需求而定
};


template <typename T >
struct str_policy;
 
template < >
struct str_policy< T1 >
{
    static T1 Init( .......... )
    {
        return ...........;
    }
};
 
template < >
struct str_policy< T2 >
{
    static T2 Init( .......... )
    {
        ...........
        return .........;
    }
};
 
template< typename T, 
          template< typename > class traits = str_traits, 
          template< typename > class policy = str_policy
        >
struct str_c
{
    typedef typename traits< T >::type member_type;
    static member_type s_body;
};
 
template< typename T >
typename str_c< T >::member_type str_c< T >::s_body = policy< member_type >::Init( ... );
Init的形参可以定制,甚至str_c内部的静态变量个数也可以定制。
tofu_ 2013-03-22
  • 打赏
  • 举报
回复
如果不需要同时使用多字节和宽字节,那么6#所说的_T("")和TEXT("")就够了。而且这种情况下甚至都没有必要定义这个str_c模板。 如果要同时使用多字节和宽字节,简单使用_T("")和TEXT("")还不够。 STR str_c<STR>::_sBody=TEXT("name"); 这里TEXT是根据编译环境来决定的,而显然这里应该是根据STR类型来决定。 这种修改字符的东西不适合用traits来解决。宏更擅长这些东西,就像#和##预处理功能。policy与此问题貌似不相关。硬要用traits写的话,大概是这样:

#include <iostream>
#include <string>
using namespace std;

template <typename StrType>
struct str_traits;

template <>
struct str_traits<string>
{
    static string format(const char* str)
    {
        return string(str);
    }
};

template <>
struct str_traits<wstring>
{
    static wstring format(const char* str)
    {
        const int MAX_LENGTH = 256;
        wchar_t wstr[MAX_LENGTH];
        // 转换多字节到宽字节,例如调用MultiByteToWideChar
        return wstring(wstr);
    }
};

template <typename StrType>
struct str_c
{
    static StrType s_body;
};

template <typename StrType>
StrType str_c<StrType>::s_body = str_traits<StrType>::format("中国");

int main(int argc, char **argv)
{
    cout << str_c<string>::s_body << endl;
    return 0;
}
但是你能忍受如此麻烦的初始化方式吗? 我觉得,你需要编写一个脚本,专门读取string str_c<string>::s_body = "name"语句并生成wstring str_c<wstring>::s_body = L"name"。
xiaohuh421 2013-03-22
  • 打赏
  • 举报
回复
_T("") TEXT("")不知道是不是你需要的, 根据编译环境决定常量串是宽字节还是多字节 STR str_c<STR>::_sBody=TEXT("name");
miliggate 2013-03-22
  • 打赏
  • 举报
回复
引用 2 楼 supermegaboy 的回复:
简单点可以对_sBody做一个特化,例如: C/C++ code?12template<>const wchar_t* str_c< const wchar_t* >::_sBody = L"name"; 但更灵活、更具扩展性的做法是加一个traits和policy。
这两个具体是什么意思呢? 求解说..
miliggate 2013-03-22
  • 打赏
  • 举报
回复
引用 3 楼 tofu_ 的回复:
C/C++ code?1234567891011121314151617181920template <typename _CharT>struct str_c; template <>struct str_c<char>{ typedef string string_type; static string_type s_body;}; str_c<char>……
..可以用,但是我想要初始化的静态变量还有N多。。 这样的话就相当于把代码在写一次 ..楼主很懒。。
tofu_ 2013-03-22
  • 打赏
  • 举报
回复

template <typename _CharT>
struct str_c;

template <>
struct str_c<char>
{
    typedef string string_type;
    static string_type s_body;
};

str_c<char>::string_type str_c<char>::s_body = "中国";

template <>
struct str_c<wchar_t>
{
    typedef wstring string_type;
    static string_type s_body;
};

str_c<wchar_t>::string_type str_c<wchar_t>::s_body = L"你好";
先来一个声明,然后针对需要的类型特化,用其他类型特化时会编译报错。
飞天御剑流 2013-03-22
  • 打赏
  • 举报
回复
简单点可以对_sBody做一个特化,例如:
template<>
const wchar_t* str_c< const wchar_t* >::_sBody = L"name";
但更灵活、更具扩展性的做法是加一个traits和policy。
billzheng 2013-03-22
  • 打赏
  • 举报
回复
Are you making mistake? your _sBody is string type, it's not wstring type.

64,685

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧