C++特质问题

发布于 2024-09-04 18:51:47 字数 571 浏览 6 评论 0原文

我有一个模板类

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

[旋木] 2024-09-11 18:51:47

您可以像下面这样专门化类的一部分:

template <typename Data>
class C
{
  void foo();

  // lot of other stuff
};

// specialize part of class C 
// (some members of a class C will have specific 
//  implementation for specific types)
template<> void C<int>::foo() { std::cout << "int" << std::endl; }
template<> void C<std::string>::foo() { std::cout << "string" << std::endl; }
// same for goo

C++ 标准 14.7/3 和 14.5.2/2 允许上述语法。无需多次重写 C 类中的所有内容。

请注意,不允许以这种方式部分特化模板类。例如,您不能以这种方式为 DataData* 类型定义不同的函数。

You could specialize part of class like follows:

template <typename Data>
class C
{
  void foo();

  // lot of other stuff
};

// specialize part of class C 
// (some members of a class C will have specific 
//  implementation for specific types)
template<> void C<int>::foo() { std::cout << "int" << std::endl; }
template<> void C<std::string>::foo() { std::cout << "string" << std::endl; }
// same for goo

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 and Data* types in this way.

随心而道 2024-09-11 18:51:47

1) 1 与 2 的相对优点是什么?

内置函数的包装器使 C 保持简单。 Traits 保留内置插件。 <代码>:)
您还可以尝试将根据 Data 不同的代码分解到基类模板中并对其进行专门化。

2) 我的特征类将有静态方法。特征类也可以有非静态方法吗?我看到大多数特征类都在 STL 中定义常量。

我什至不确定它是否仍然被称为“特征”,如果它有状态的话。
FWIW,我通常仅将那些排除其他类型信息的特征归类为特征。当谈到行为时,我宁愿将其称为政策。然而,我确实看到 std::char_traits 不符合这些定义。 <代码>:(
不管怎样,如果它有非静态成员,那么它就有状态,我不会再称这个特征了。

3)我应该将特征类设置为全局还是应该将它们作为类 C 的模板参数传递?

将其作为模板参数传递仅有意义您希望 C 的用户为他们作为数据传递的任何内容提供自己的特征。如果 int 总是有一个特征模板,那么类就可以使用它。如果用户可能想出自己的 int 特征,他们需要一种方法将其传递给 C

1) what are the relative merits of 1 vs 2?

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.

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.

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.

3) Do I make the traits classes global or should I pass them in as a template parameter for class C?

Passing it as a template parameter only makes sense of you want users of C provide their own traits for whatever they pass in as Data. If there will always ever be one traits template for int the class can just use that. If users might come up with their own traits for int, they need a way to pass it to C.

逆光下的微笑 2024-09-11 18:51:47

各有半打?我不知道在一般意义上使用其中一种与另一种的任何先验理由。你所问的问题都不让我认为你应该选择其中之一。我唯一能想到的一件事是,选择 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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文