C++关于模板类型的设计问题

发布于 2024-09-03 16:53:37 字数 583 浏览 6 评论 0原文

我有一个模板类

  template <typename T>
    class MyContainerClass

对于要替换 T 的类型,它必须满足许多要求:例如, get_id()、int data() 等。

显然,基本类型 (POD) 都是不可替代的。我可以提供的一种方式 这是通过提供这些功能的 POD 的包装器实现的。这是可以接受的吗 方式?

另一种方法是将模板更改为:

template < typename T, typename C=traits<T> >
class MyContainerClass

并在 MyContainerClass 内部,对 T 对象调用 Traits::data() 而不是 data()。 我将专门研究 traits、traits 等。

这是好的设计吗?我如何设计这样的特征类(完全静态方法或允许 用于继承)?或者包装类是一个好的解决方案吗?

还有哪些其他选择?

I have a templated class

  template <typename T>
    class MyContainerClass

For types to be substituted for T, it has to satisfy many requirements: for example,
get_id(), int data(), etc.

Obviously none of the fundamental types (PODs) are substitutable. One way I can provide
this is via wrappers for the PODs that provide these functions. Is this an acceptable
way?

Another way would be to change the template to:

template < typename T, typename C=traits<T> >
class MyContainerClass

and inside MyContainerClass, call traits::data() instead of data() on T objects.
I will specialize traits<int>, traits<const char *> etc.

Is this good design ? How do I design such a traits class (completely static methods or allow
for inheritance) ? Or are the wrapper classes a good solution?

What other alternatives are there?

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

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

发布评论

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

评论(4

毁梦 2024-09-10 16:53:37

解决这个问题的另一种方法是将模板专门用于特定类型,例如,

template <>
    class MyContainerClass<int>

然后显然实现使用带有整数的容器所需的一切。

但我认为特征解决方案要好得多。它还允许您在其他容器和稍后创建的其他类中重用这些特征。

Another way to solve it would be to specialize the template for specific types, e.g.

template <>
    class MyContainerClass<int>

And then obviously implement everything needed to use the container with ints.

But I think the traits-solution is a lot better. It will also allow you to reuse the traits in other containers and other classes you make later.

深者入戏 2024-09-10 16:53:37

您会发现 std 相当广泛地使用 type_traits。您可以检查它们是否确实满足您的需求,而且,这应该是一个很好的提示,表明特征结构规范是正确的方法。

You'll observe that std uses type_traits quite extensively. You might check if they actually serve your needs, but also, this should be a good hint to you that a traits struct spec is the right way to go.

盗琴音 2024-09-10 16:53:37

尽管其他人似乎都赞成专业化,但我会选择特质。原因有两个:

  1. 他们是“使用专业化”——变相的想法,因为他们也使用专业化,但他们的想法是外部化专业化,这样它们就不会污染您的实际算法。

  2. 在标准库中使用它们是一种经过充分验证的众所周知的技术,每个人都会立即认识到。相比之下,专业化在标准库中使用得并不多。 (我刚才是不是听到有人大喊 std::vector?)。

Even though everybody else seems to favor specialization, I'd go with traits. There's two reasons for that:

  1. They are the "use specialization"-idea in disguise, since they use specialization, too, but their idea is to externalize the specializations, so that they won't pollute your actual algorithms.

  2. Being used in the standard lib they are a well-proven and well-known technique everybody recognizes immediately. In contrast, specializations aren't used all that much in the std lib. (Did I just hear someone yelling std::vector<bool>?).

那片花海 2024-09-10 16:53:37

出于不同的原因,我也喜欢特质。使用 sfinae,您可以获得一个有效的 is_class 谓词:

template <typename T>
struct traits
{
    static const bool is_class = sizeof(test<T>(0)) == 1;

private:
    template <typename U> char (&test(int U::*))[1];
    template <typename> char (&test(...))[2];
};

并专门研究非类类型,而不必枚举所有基本类型(这需要一些宏才能使其可维护......)

I'd favor traits too, for a different reason. Using sfinae, you can get a working is_class predicate :

template <typename T>
struct traits
{
    static const bool is_class = sizeof(test<T>(0)) == 1;

private:
    template <typename U> char (&test(int U::*))[1];
    template <typename> char (&test(...))[2];
};

and specialize on non-class types without having to enumerate all the basic types (which needs some dose of macros to be made maintainable...)

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