强制模板函数的泛型类型继承某个类[重复]

问题描述 投票:0回答:3

在 Rust 编程语言中,您可以声明一个带有必须实现特征的泛型类型参数的函数。 (不知道的人可以认为

implement
inheritance
trait
class
)。因此,传递给该函数的对象必须实现该特征。例如:

// Define a function `printer` that takes a generic type `T` which
// must implement trait `Display`.
fn printer<T: Display>(t: T) {
    println!("{}", t);
}

现在我的问题是,如何在 C++ 中定义这样的模板函数来强制类型继承一些基类?

c++
3个回答
3
投票

您可以使用

std::is_base_of
来检查类型是否具有特定的基类。利用 SFINAE 看起来像:

template <typename T, std::enable_if_t<std::is_base_of_v<BASE_CLASS, T>, bool> = true>
ret_type function_name(T t)
{
    // your code
}

仅当

T
派生自
BASE_CLASS
或者是相同类型时,上述模板才会被实例化。


1
投票

在 C++20 中,您可以使用

requires
来简化这一过程。 由于在撰写本文时 C++20 尚未广泛普及,因此这里有一个向后兼容的示例:

template<typename T>
std::enable_if_t<std::is_base_of_v<Display, T>> fn(const T& t)
{
    // your favorite println implementation over t
}

如果您想返回一个值,请使用

std::enable_if_t<condition, return_type>


0
投票

C++20 方式:

template <std::derived_from<Display> T>
void printer(const T &value)
{
    // ...
}

或者缩写模板语法:

void printer(const std::derived_from<Display> auto &value)
{
    // ...
}

请注意,

std::derived_from
std::is_base_of_v
之间存在一些区别(除了其中一个是概念):后者检查任何基础,而前者检查明确的公共基础。如果这就是您想要的,但您没有 C++20,您可以额外检查
std::is_convertible_v<A *, B *>

© www.soinside.com 2019 - 2024. All rights reserved.