c++ - std::is_pointer<T>::value为什么不能应用于条件操作符operator ? :

浏览:31日期:2023-05-28

问题描述

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

这种写法是没有问题的:

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; }}

而下面这种写法却有问题,实在不理解是怎么回事?

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

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

问题解答

回答1:

你可以装一个clang然后看看clang的编译结果.具体来讲就是foo(1)的时候, *val表达式是非法的, 因为val是int类型的;而一个foo(int*)的时候, *val是一个int类型的, 而val是一个int*类型的, 这个在?:表达式里面是非法的, ?:表达式要求两个子表达式都能找到std::commen_type.

PS:针对你这个问题,实际上要做的是针对指针类型写一个偏特化,而不是通过is_pointer来做.

手动模板实例化一下, 针对int类型:

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

再来看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;}

相关文章: