c++ - std::is_pointer<T>::value为什么不能应用于条件操作符operator ? :
PHP中文网
PHP中文网 2017-04-17 13:08:18
0
1
827

最近正在看《C++标准库-自学教程与参考手册》(第二版),Section 5.4.1,page 122:

  1. 这种写法是没有问题的:

template <typename T> void foo (const T& val) {
    if (std::is_pointer<T>::value) {
        std::cout << "foo() called for a pointer" << std::endl;
    } else {
        std::cout << "foo() called for a value" << std::endl;
    }
}
  1. 而下面这种写法却有问题,实在不理解是怎么回事?

template <typename T> void foo (const T& val) {
    std::cout << (std::is_pointer<T>::value ? *val : val) 
        << std::endl;
}

难道operator ?: 不是在判断完条件是否正确再对后面的表达式进行求值吗?!

PHP中文网
PHP中文网

认证高级PHP讲师

reply all(1)
阿神

You can install clang and see the compilation results of clang.
Specifically, when foo(1), the *val expression is illegal because val is of type int;
And a When foo(int*), *val is of type int, and val is of type int*. This is illegal in ?: expression, and ?: expression requires both subexpressions to be valid. Found std::commen_type.

PS: Regarding your question, what we actually need to do is to write a partial specialization for the pointer type instead of doing it through is_pointer.

Manual template instantiation, for int type:

template <> void foo<int> (const int& val /*=1*/) {
    std::cout << 
        std::is_pointer<int>::value ? 
            *val         //自己看, *1是不是合法的表达式
            : 
            val          //1是合法的表达式
        << std::endl;
}

Let’s look at the instantiation of int*:

template <> void foo<int*> (const int*& val) {
    std::cout << 
        std::is_pointer<int>::value ? 
            *val         //*val是int类型, 合法
            : 
            val          //val是int*类型, int*和int类型不能相互的隐式转换
        << std::endl;
}
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template