搜尋

首頁  >  問答  >  主體

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

最近正在看《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中文网2806 天前833

全部回覆(1)我來回復

  • 阿神

    阿神2017-04-17 13:10:18

    你可以裝一個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;
    }

    回覆
    0
  • 取消回覆