[英]C++ type_traits / how can i not use parents member function with type_traits?
[英]C++ STL type_traits question
我正在观看最新的C9讲座并注意到一些有趣的东西......
在他对type_traits的介绍中,Stephan使用了以下(正如他所说的,做作的)示例:
template <typename T>
void foo(T t, true_type)
{
std::cout << t << " is integral";
}
template <typename T>
void foo(T t, false_type)
{
std::cout << t << " is not integral";
}
template <typename T>
void bar(T t) { foo(t, typename is_integral<T>::type()
); }
这看起来要复杂得多:
template <typename T>
void foo(T t)
{
if(std::is_integral<T>::value
)
std::cout << "integral";
else
std::cout << "not integral";
}
这样做的方法有问题吗? 他的方式更好吗? 为什么?
谢谢。
基本上,第一个选项在编译时使用关于类型的“完整性”的知识,第二个选项 - 将此知识移动到运行时。
这意味着我们可以使用不可编译为非整数类型的整数类型代码。
下面的例子应该说明不同之处。 让我们添加struct X:
struct X
{
X(int)
{
}
};
并修改一个foo如下:
template <typename T> void foo(T t, true_type)
{
std::cout << t << " is integral";
X x(t);
}
template <typename T> void foo(T t, false_type)
{
std::cout << t << " is not integral";
}
然后:
template <typename T> void bar(T t)
{
foo(t, typename is_integral<T>::type());
}
仍然会为所有T类型编译(包括整数类型;它可能会导致警告,但会编译)。
其他等效代码:
template <typename T> void foo(T t)
{
if(std::is_integral<T>::value)
{
std::cout << "integral";
X x(t);
}
else
std::cout << "not integral";
}
通常会无法编译,因为您将无法为其他类型实例化X,而最终浮点和用户定义的类具有运算符int()(运算符short()或运算符long()将不会)。
对于这样一个小的,人为的例子,第一种方式没有太大的优势。 当您遇到更复杂的情况时,优势就来了。 它基本上类似于在面向对象的编程中使用基于继承的多态或if / switch语句。 更复杂的解决方案可以提供更大的灵活性 您可以轻松添加类型而无需修改现有代码。
如果你知道你将需要的所有类型(例如你使用布尔值作为例子),那么更简单的解决方案可能会更好。 但是如果你没有固定的要求(什么时候需要修复?),从长远来看,更复杂但更灵活的解决方案可能会更容易。
使用第一种方法,您可以在不使用if/else
或switch
情况下实现静态分派。
template <typename T>
void Dispatch(T t)
{
//Call foo(T, true_type) or foo(T, false_type)
//depending upon the *type* of second parameter.
foo(t, typename is_integral<T>::type());
}
使用第二种方法,你要使用if/else
或switch
块来实现它,
template <typename T>
void Dispatch(T t)
{
//Call foo(T, true_type) or foo(T, false_type)
//depending upon the *value* of value.
if(std::is_integral<T>::value)
foo(t, true_type());
else
foo(t, false_type());
}
但是如果你想在不使用if/else
情况下实现你的Dispatch()
函数,并且同时你想使用std::is_integral<T>::value
,那么你必须重新编写你的foo()
函数,像这样,
template <bool b>
void foo(T t)
{
std::cout << t << " is integral";
}
template <>
void foo<false>(T t)
{
std::cout << t << " is not integral";
}
你的Dispatch()
函数看起来像,
template <typename T>
void Dispatch(T t)
{
//using std::is_integral<T>::value!
const bool selector = (bool) std::is_integral<T>::value;
foo<selector>(t);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.