gpt4 book ai didi

c++ - 在模板中指定允许的参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:38:17 25 4
gpt4 key购买 nike

我能否准确指定模板可以接收的参数类型?例如,我想创建一个模板,它只能用 A 类或扩展类 A 的类实例化。在 Java 中,泛型通过以下方式支持这一点:

class B<T extends A> { }

可以用 C++ 中的模板实现类似的东西吗?

template <typename T (?)> class B { }

最佳答案

有两种方法可以做到这一点。

首先,通过使用 std::enable_if 的隐藏虚拟模板参数用std::is_base_of<A, T>::value作为条件。如果后一个表达式计算为 false , 然后是嵌套的 typestd::enable_if 中不存在.如果您在重载函数上使用它,SFINAE 则意味着“替换失败不是错误”,并且有问题的重载将从可行函数集中删除。但是在这种情况下,没有其他类模板可以匹配您的调用,然后您就会遇到编译时错误。

SFINAE 是一种非常微妙的机制,很容易出错。例如。如果你有多个具有不同 SFINAE 条件的类特化,你必须确保它们都是非重叠的,否则你会产生歧义。

其次,你可以做一个简单的static_assertstd::is_base_of<A,T>::value在类的主体内。与 SFINAE 方法相比,此方法的优点是您还可以指定更易读的错误消息。一个缺点是你总是会出错,而且你不能默默地抑制这个特定的模板并选择另一个。但总的来说,我认为这种方法适合你的情况。

#include<type_traits>

class A {};
class C: public A {};
class D {};

// first alternative: SFINAE on hidden template parameter
template
<
typename T,
typename /* dummy */ = typename std::enable_if<
std::is_base_of<A, T>::value
>::type
>
class B
{
};

// second alternative: static_assert inside class
template
<
typename T
>
class E
{
static_assert(std::is_base_of<A, T>::value, "A should be a base of T");
};

int main()
{
B<A> b1;
B<C> c1;
//B<D> d1; // uncomment this line to get a compile-time error

E<A> b2;
E<C> c2;
//E<D> d2; // uncomment this line to get a compile-time error

return 0;
}

正如评论中指出的那样,您可以使用合适的 C++11 编译器(VC++ 2010 或更高版本,gcc 4.5 或更高版本)或 Boost 或 TR1 库来获取 <type_traits>功能。但是请注意 std::is_base_of<A, A>::value评估为 true ,但是旧的boost::is_base_of<A, A>::value用于评估 false .

关于c++ - 在模板中指定允许的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11963287/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com