繁体   English   中英

C ++ STL 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/elseswitch 情况下实现静态分派。

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/elseswitch块来实现它,

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM