特征和传递特征作为模板参数

时间:2011-02-11 07:48:26

标签: c++ templates idioms traits

什么时候将traits作为模板参数传递,而不是简单地使用一些现有的traits结构,如

typedef basic_ofstream< char, char_traits<char> >

VS。

typedef basic_ofstream< char >

我有一些平铺类,我希望有一些共同点(特征),所以我设计了tile_traits来包含有关平铺的所有基本信息,例如int_type和{{1像这样:

flag_type

设计特征是否被认为是 traits-blob

3 个答案:

答案 0 :(得分:13)

特征的设计与其他任何东西一样多。没有硬和 快速回答这里。我相信这个问题没有得到解决,因为它是 在不了解问题的情况下,不可能给出一个好的答案 你在解决。

一般来说,traits类是一个有用的“定制点”。也就是说,如果你 正在设计模板:

template <class Tile>
class TileContainer
{
    ...
};

TileContainer可能会将tile_traits<Tile>用于Tile的某些属性。 TileContainer的客户可以专门化tile_traits<MyTile> 在默认特征(如果存在)时传达属性的变体 是不正确的。

到目前为止,我认为我没有说过任何你不知道的事情 问题的措辞方式。)

我认为你的问题是:

你应该设计:

A)

template <class Tile, class Traits = tile_traits<Tile>>
class TileContainer
{
    // uses Traits
};

或:

B)

template <class Tile>
class TileContainer
{
    // uses tile_traits<Tile>
};

C ++ 03和即将推出的C ++ 0x标准中都有两种设计的例子。

示例A设计:

template<class charT, class traits = char_traits<charT>,
                      class Allocator = allocator<charT>>
    class basic_string;  // both traits and Allocator are traits

template <class Codecvt, class Elem = wchar_t,
                         class Tr = char_traits<Elem>>
    class wbuffer_convert;

template <class T, class Allocator = allocator<T>>
    class vector; // Allocator is a A-trait that uses another
                  // B-trait internally:  allocator_traits<Allocator>

template <class charT, class traits = regex_traits<charT>>
    class basic_regex;

示例B设计:

template<class Iterator> struct iterator_traits;
template <class Alloc> struct allocator_traits;
template <class Ptr> struct pointer_traits;
template <class Rep> struct treat_as_floating_point;
template <class Rep> struct duration_values;

我唯一的建议是没有正确或错误的设计。使用:

template <class Tile>
class TileContainer
{
    // uses tile_traits<Tile>
};

当您确定通过专业化始终可以满足客户的需求时 tile_traits<MyTile>

使用:

template <class Tile, class Traits = tile_traits<Tile>>
class TileContainer
{
    // uses Traits
};

当您怀疑您的客户可能需要不同的特征时 平铺,或者当你想强制TileContainer的类型不同时 使用了除tile_traits之外的一些特征。

答案 1 :(得分:6)

如果您可以看到人们会为同一数据类型传递不同的特征,则需要将traits类作为模板参数。如果你的瓷砖每个T都有相同的tile_traits,你可以直接使用它。

如果您看到有人会使用my_special_traits,则需要将其作为单独的模板参数。

答案 2 :(得分:1)

看到你可以提供特征的默认值,并且让traits参数总是更灵活,我会选择这种方法,除非你有一些特定的原因,为什么你不能这样做。

template<class Bar,class Traits=FooTraits<Bar> >
class Foo
{};