首页 > 解决方案 > 模板中的 C++ 数据类型

问题描述

我有一个关于在 C++ 中使用模板的正确/正确方法的问题。

假设我们有一个这样的模板类:

template <typename T> class Foo
{
    public:
        T add(T n1, T n2);
};

template <typename T> T Foo<T>::add(T n1, T n2)
{
    return(n1 + n2);
}

这将非常适用于基本数据类型,如 int、double、float、char ...等。

Foo <int> foo_int;
std::cout << std::to_string(foo_int.add(2, 5)) << std::endl;

Foo <double> foo_double;
std::cout << std::to_string(foo_double.add(2.2, 6.1)) << std::endl;

Foo <char> foo_char;
std::cout << std::to_string(foo_char.add('A', 'm')) << std::endl;

但这不适用于复杂的数据类型,比如这个:

class Bar
{
    public:
        std::string bar;
};

Bar bar_1;
Bar bar_2;
Foo <Bar> foo_bar;

std::cout << std::to_string(foo_int.add(bar_1, bar_2)) << std::endl;   

是否可以编写仅适用于少数数据类型的模板,或者仅在适用于所有类型的数据类型(如 std::vector)的情况下使用模板。

万一,如果编写仅适用于少数数据类型的模板是正确的,那么应该如何编写呢?在 class 的情况下Foo,我会知道它Foo仅适用于基本数据类型,但假设我将代码提供Foo给 Alice,她不知道。所以如果她使用Foo复杂的数据类型,她会得到一个编译器错误。

有没有告诉编译器/编程器模板只适用于某些数据类型,除了编译器会抛出的错误。

标签: c++templatestypes

解决方案


但这不适用于复杂的数据类型,比如这个:

那是因为Bar不提供Bar::operator+(Bar, Bar)- 如果提供,它将与您的模板一起使用。


编写仅适用于少数数据类型的模板是否可以

根据您的用例,是的。您通常希望支持符合特定概念的所有数据类型,但有时您可能还希望支持一组固定的类型。


有没有告诉编译器/编程器模板只适用于某些数据类型,除了编译器会抛出的错误。

如果您希望您的模板适用于符合特定接口的所有类型,您需要使用概念(在 C++20 中可用,在 C++11 中可以模拟)。

您可以使用检测习语检查有关类型的属性,并使用static_assert(或 SFINAE)为您的类的用户提供编译时错误。


推荐阅读