关于trait和policy的互操作

飞天御剑流 2012-10-09 08:16:38
加精
近日写模板的时候遇到一个问题,与trait和policy之间的互操作有关,下面是简化后的代码:


template < typename T >
class TraitSet;

template<>
class TraitSet< int >
{
public:

typedef int TypeT;
};

template<>
class TraitSet< long >
{
public:

typedef long TypeT;
};

................. //有很多trait

template< typename T >
class DefaultAction
{
public :
............
static T GetData( void )
{
if( typeid( T ) == typeid( int ) )
{
return 10;
}
if( typeid( T ) == typeid( long ) )
{
return 20;
}
..................... //有很多个typeid
return T( );
}
...............
};

........................ //有一些policy,每个policy都有GetData

template< typename T,
typename Policy = DefaultAction< T >,
template < typename > class Trait = TraitSet >
class ResultSet
{
public :
..............
static T GetResult( void )
{
..............
typename Trait<T>::TypeT Data = Policy::GetData( );
...............
return Data;
}
............
};

在ResultSet::GetResult中需要给Data赋值,其值与不同的policy和不同的trait都有关,在Policy::GetData中需要根据不同的trait返回不同的内容。我只想到了在Policy::GetData内部使用typeid分辨不同的trait,由于有很多trait,造成每个policy都有一大串typeid,这写法太丑陋了,使用运行时RTTI也有点不爽,请问各位有否代码更优雅的意见?
...全文
2337 88 打赏 收藏 转发到动态 举报
写回复
用AI写文章
88 条回复
切换为时间正序
请发表友善的回复…
发表回复
LAONINGA098 2012-10-22
  • 打赏
  • 举报
回复
研究下
ChunXiatpQiuDong 2012-10-21
  • 打赏
  • 举报
回复
很好,学习学习
LAONINGA098 2012-10-20
  • 打赏
  • 举报
回复
研究下
matthe123 2012-10-18
  • 打赏
  • 举报
回复
谢谢分享,很有用
huafangwu 2012-10-18
  • 打赏
  • 举报
回复
牛人 啊!!!
狼啊郎 2012-10-17
  • 打赏
  • 举报
回复
据不同的trait返回不同的内容。我只想到了在Policy::GetData内部使用typeid分辨不同的trait,由于有很多trait,造成每个policy都有一大串typeid,这写法太丑陋了,使用运行时RTTI也有点不爽,请问各位有否代码更优雅的意见?
飞天御剑流 2012-10-17
  • 打赏
  • 举报
回复
[Quote=引用 63 楼 的回复:]
引用 58 楼 的回复:

引用 56 楼 的回复:

引用 55 楼 的回复:

引用 47 楼 的回复:
引用 45 楼 的回复:

引用 37 楼 的回复:

引用 28 楼 的回复:

7楼、10楼、19楼:

policy最好还是不要做全特化,特别是我这个例子,因为policy跟trait不一样,trait一般而言不含有实体代码,而policy正好相反,在p……
[/Quote]
你误会偶的意思了,偶并没有认为"只特化 RTTI 的方法肯定不会导致代码膨胀",别胡思乱想搞得太复杂了,原因仅仅是只特化需要特化的那部分就行了。
sally3300 2012-10-17
  • 打赏
  • 举报
回复
谢谢,学习到了
liubin502347201 2012-10-16
  • 打赏
  • 举报
回复
好东西研究研究
answeallen 2012-10-14
  • 打赏
  • 举报
回复
plouzhu hao ren

fallening 2012-10-14
  • 打赏
  • 举报
回复
[Quote=引用楼主 的回复:]
近日写模板的时候遇到一个问题,与trait和policy之间的互操作有关,下面是简化后的代码:

C/C++ code

template < typename T >
class TraitSet;

template<>
class TraitSet< int >
{
public:

typedef int TypeT;
};

template<>
cla……
[/Quote]
我来提供个思路:
template<typename T>
struct type_tag{};

template<typename T>
struct default_action
{
typedef T value_type;

value_type operator()(const type_tag<int>&) const
{
return 10;
}

value_type operator()(const type_tag<long>&) const
{
return 20;
}
};

template<typename T, typename Action = default_action<T> >
struct result_extract
{
typedef T value_type;
typedef Action action_type;
typedef result_extract self_type;

value_type operator()() const
{
return self_type()( type_tag<T>() );
}

private:
value_type operator()(const type_tag<int>& tag) const
{
return action_type()( tag );
}
value_type operator()(const type_tag<long>& tag) const
{
return action_type()( tag );
}
};

#include <iostream>

int main()
{
std::cout << result_extract<int>()() << "\n";
std::cout << result_extract<long>()() << "\n";
return 0;
}


使用了 type_tag 是为了应付 int2type/string2type 的情形。
cds81098 2012-10-14
  • 打赏
  • 举报
回复
其实很多的网站都可以用的到
Jinhao 2012-10-13
  • 打赏
  • 举报
回复
借用8楼的思路

namespace for_actions
{
template<typename T>
struct def_value
{
T value;
};

template<>
struct def_value<int>
{
enum{value = 10};
};

template<>
struct def_value<long>
{
enum{value = 20};
};
}

template< typename T >
class DefaultAction
{
public :
typedef for_actions::def_value<T> data_reader;
};

struct A
{
A(const std::string& s);
};

namespace for_actions
{
template<>
struct def_value<A>
{
A value;

def_value()
: value("构造你妹")
{}
};
}

int main()
{
DefaultAction<A>::data_reader().value;
std::system("pause");
}
/////////////////////
static T GetResult( void )
{
..............
typename Trait<T>::TypeT Data = typename Policy::data_reader().value;
...............
return Data;
}
ri_aje 2012-10-13
  • 打赏
  • 举报
回复
[Quote=引用 58 楼 的回复:]

引用 56 楼 的回复:

引用 55 楼 的回复:

引用 47 楼 的回复:
引用 45 楼 的回复:

引用 37 楼 的回复:

引用 28 楼 的回复:

7楼、10楼、19楼:

policy最好还是不要做全特化,特别是我这个例子,因为policy跟trait不一样,trait一般而言不含有实体代码,而policy正好相反,在policy上做全特化很容……
[/Quote]
我的观点和你一样,不要依赖标准没有保证的行为。
另外,你说只特化 RTTI 的方法肯定不会导致代码膨胀,是不是因为类模板嵌套类模板及其特化肯定是按需实例化?因为外层类模板实例化的时候,标准保证只有真正用到的成员才会相应的实例化。而全局域类模板的特化不存在这种“保护”,和普通类定义一样,因此标准不保证这样的定义不生成代码。你是这么理解的吗?
tza2003 2012-10-13
  • 打赏
  • 举报
回复
不太懂,过来看看。
冷月清晖 2012-10-12
  • 打赏
  • 举报
回复
看到几个凌晨回帖的,对你们的敬业精神表示膜拜。
飞天御剑流 2012-10-12
  • 打赏
  • 举报
回复
[Quote=引用 56 楼 的回复:]

引用 55 楼 的回复:

引用 47 楼 的回复:
引用 45 楼 的回复:

引用 37 楼 的回复:

引用 28 楼 的回复:

7楼、10楼、19楼:

policy最好还是不要做全特化,特别是我这个例子,因为policy跟trait不一样,trait一般而言不含有实体代码,而policy正好相反,在policy上做全特化很容易造成程序体积问题的。这也是偶一开……
[/Quote]
我换个角度,举另外一个类似的例子,在c/c++标准中,整形提升是必然发生的,但是,标准允许实现过程可以灵活处理,例如
signed char a = -10;
signed char b = 20;
a+b;

如果一个实现确定a+b的结果不会产生溢出,那么它可以选择直接相加a和b而不进行实际的提升,但是,结果必须与提升的结果相同,这是标准给予的自由。那么,我们是否可以认为整形提升不是必然的呢?不!它仍然是必然进行的!

回到我们这个例子,我们不能因为编译器存在优化而随意或者故意挑战标准所规定的必然行为,特别是存在更好的解决方案的前提下,例如这里的只对RTTI部分的特化,我们应该依赖有保证的行为,而不能依赖无保证的行为,这样写出来的代码才是健壮的。
ri_aje 2012-10-12
  • 打赏
  • 举报
回复
[Quote=引用 55 楼 的回复:]

引用 47 楼 的回复:
引用 45 楼 的回复:

引用 37 楼 的回复:

引用 28 楼 的回复:

7楼、10楼、19楼:

policy最好还是不要做全特化,特别是我这个例子,因为policy跟trait不一样,trait一般而言不含有实体代码,而policy正好相反,在policy上做全特化很容易造成程序体积问题的。这也是偶一开始想避免的问题,只是,没有考虑到象……
[/Quote]
你误会了,我知道标准对特化是否对应代码没有规定,也知道特化是定义而非声明,也知道你说的标准和实现之间的关系,就像标准没说虚表一样。不过即然存在这种不确定性,你为何就肯定特化容易造成体积增长呢?对于标准没说清或故意留有余地的事,通过直观理性思维辅助编译器具体实现去理解不是很自然的吗。并非我要从编译器理解语言,而是标准本身造成的空白只能通过这种方法填补啊。
飞天御剑流 2012-10-11
  • 打赏
  • 举报
回复
[Quote=引用 37 楼 的回复:]

引用 28 楼 的回复:

7楼、10楼、19楼:

policy最好还是不要做全特化,特别是我这个例子,因为policy跟trait不一样,trait一般而言不含有实体代码,而policy正好相反,在policy上做全特化很容易造成程序体积问题的。这也是偶一开始想避免的问题,只是,没有考虑到象8楼那样仅对RTTI部分全特化。

表示很困惑。语言要求程序中实际用到的特化才会生成相应……
[/Quote]
显式特例化不是按需实例化。
飞天御剑流 2012-10-11
  • 打赏
  • 举报
回复
参加讨论的都有分,各位不用担心。
加载更多回复(41)

64,637

社区成员

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

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