我有一个模板类
template <typename Data>
class C
{
.....
}
在大多数情况下,我依赖编译器来让我用类型替换数据。
我在 Data 类型的对象上调用方法 foo()、goo(),所以我替换的内容需要提供
那。
我现在需要用 int 和 string 替换我的数据类型。我不想专攻
因为类已经太大了,需要专门化每个方法(只需更改少量代码)。
我的选项(请告诉我是否有更多选项)
1)我可以提供 int 和 string 的包装类,它们实现 foo()、goo() 等方法
2) 提供一个特征类
在提供 foo()、goo() 的类的对象上调用 foo() 或 goo() 的特征
(这些是我目前的可替代课程)
并将这些类专门用于 int 和 string。
问题
1) 1 与 2 的相对优点是什么?
2)我的特征类将有静态方法。特征类也可以有非静态方法吗?我发现大多数特征类都在 STL 中定义常量。
3)我应该将特征类设置为全局还是应该将它们作为模板参数传递
对于C类?
I have a templated class
template <typename Data>
class C
{
.....
}
In most situations, I depend on the compiler to let me substitute types for Data.
I call methods foo(), goo() on objects of type Data, so what I substitute needs to provide
that.
I now need to substitute int and string for my Data type. I do not want to specialize
because the class is already too big and would require specializing each method (with only small code change).
My options (please tell me if there are more)
1) I can provide wrapper classes around int and string which implement the methods foo(), goo() etc
2) provide a traits class
traits that calls foo() or goo() on objects of classes that provide foo(),goo()
(these are my present substitutable classes)
and specialize these classes for int and string.
Questions
1) what are the relative merits of 1 vs 2?
2) My traits classes will have static methods. Can a traits class have non-static methods as well? I see most traits classes define constants in the STL.
3) Do I make the traits classes global or should I pass them in as a template parameter
for class C?
发布评论
评论(3)
您可以像下面这样专门化类的一部分:
C++ 标准 14.7/3 和 14.5.2/2 允许上述语法。无需多次重写
C
类中的所有内容。请注意,不允许以这种方式部分特化模板类。例如,您不能以这种方式为
Data
和Data*
类型定义不同的函数。You could specialize part of class like follows:
The syntax above allowed by C++ Standard 14.7/3 and 14.5.2/2. There's no need to rewrite all stuff from class
C
several times.Note, that it is not allowed to partially specialize template class in such way. For instance, you cannot define different functions for
Data
andData*
types in this way.内置函数的包装器使
C
保持简单。 Traits 保留内置插件。 <代码>:)您还可以尝试将根据
Data
不同的代码分解到基类模板中并对其进行专门化。我什至不确定它是否仍然被称为“特征”,如果它有状态的话。
FWIW,我通常仅将那些排除其他类型信息的特征归类为特征。当谈到行为时,我宁愿将其称为政策。然而,我确实看到
std::char_traits
不符合这些定义。 <代码>:(不管怎样,如果它有非静态成员,那么它就有状态,我不会再称这个特征了。
将其作为模板参数传递仅有意义您希望 C 的用户为他们作为数据传递的任何内容提供自己的特征。如果
int
总是有一个特征模板,那么类就可以使用它。如果用户可能想出自己的int
特征,他们需要一种方法将其传递给C
。Wrappers around built-ins keep
C
simple. Traits keep the built-ins built-ins.:)
You could also try to factor out the code that differs depending on
Data
into a base class template and specialize that.I'm not even sure it's still called "traits" if it has state.
FWIW, I usually categorize as traits only those which factor out information about other types. When it comes to behavior, I'd rather call it a policy. I do see, however, that
std::char_traits
doesn't fit these definitions.:(
Anyway, if it it has non-static members, then it has state, and I wouldn't call this traits anymore.
Passing it as a template parameter only makes sense of you want users of
C
provide their own traits for whatever they pass in asData
. If there will always ever be one traits template forint
the class can just use that. If users might come up with their own traits forint
, they need a way to pass it toC
.各有半打?我不知道在一般意义上使用其中一种与另一种的任何先验理由。你所问的问题都不让我认为你应该选择其中之一。我唯一能想到的一件事是,选择 1 可能需要对现有功能进行较少的更改。另一方面,客户端将无法在不创建包装器的情况下仅在原语上使用该函数。
这实际上是一个细节问题,而你没有提供它们。
Half a dozen of each? I don't know of any a priori reason to use one vs. the other in a generic sense. None of what you are asking makes me think you should chose one over the other. The only one thing I can think of is that choice 1 is probably going to require less changes to the existing function(s). On the other hand, clients won't be able to just use the function on primitives without creating the wrapper.
It's really a matter of specifics and you didn't provide them.