7

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

typedef basic_ofstream< char, char_traits<char> >

对比

typedef basic_ofstream< char >?

我有一些瓦片类,我希望它们有一些共同点(特征),所以我设计tile_traits包含有关瓦片的所有基本信息,例如int_typeflag_type,如下所示:

//unspecialized
template<typename T> struct tile_traits;
//... other stuff here, declaration of a tile class
template<>
struct tile_traits<tile_class>
{
   typedef tile_class::int_type  int_type;
   typedef tile_class::flag_type flag_type;
   //other possible tile info here.
}

像这样设计特征是否被视为特征块

4

3 回答 3

13

特质的设计与其他任何事物一样都是艺术。这里没有硬性和快速的答案。我相信这个问题没有得到解答,因为如果不了解更多关于您正在解决的问题,就不可能给出一个好的答案。

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

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

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

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

我认为你的问题是:

你应该设计:

一种)

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

或者:

二)

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

当您怀疑您的客户可能需要相同 Tile 的不同特征时,或者当您希望在使用 tile_traits 以外的某些特征时强制 TileContainer 的类型不同时。

于 2011-02-13T18:53:09.480 回答
6

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

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

于 2011-02-13T16:21:35.607 回答
1

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

template<class Bar,class Traits=FooTraits<Bar> >
class Foo
{};
于 2011-02-13T16:24:27.500 回答