为什么在不同顺序下使用std::remove_reference和std::remove_const会产生不同的结果?

7
在下面的代码中,我使用了std::remove_conststd::remove_reference,但在两种情况下使用的顺序不同,导致结果不同:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <type_traits>

using namespace std;

int main()
{
    vector<string> ar = {"mnciitbhu"};
    cout<<boolalpha;
    cout<<"First case : "<<endl;
    for(const auto& x : ar)
    {
        // Using std::remove_const and std::remove_reference
        // at the same time
        typedef typename std::remove_const<
            typename std::remove_reference<decltype(x)>::type>::type TT;
        cout<<std::is_same<std::string, TT>::value<<endl;
        cout<<std::is_same<const std::string, TT>::value<<endl;
        cout<<std::is_same<const std::string&, TT>::value<<endl;
    }
    cout<<endl;
    cout<<"Second case : "<<endl;
    for(const auto& x : ar)
    {
        // Same as above but the order of using std::remove_reference
        // and std::remove_const changed
        typedef typename std::remove_reference<
            typename std::remove_const<decltype(x)>::type>::type TT;
        cout<<std::is_same<std::string, TT>::value<<endl;
        cout<<std::is_same<const std::string, TT>::value<<endl;
        cout<<std::is_same<const std::string&, TT>::value<<endl;
    } 
    return 0;
}

输出结果为:
First case : 
true
false
false

Second case : 
false
true
false

Coliru Viewer上检查一下。

我的问题是,为什么使用 std::remove_conststd::remove_reference 的顺序不同会产生不同的结果?因为我正在删除引用和 const,所以结果不应该是相同的吗?


这个参考链接(http://en.cppreference.com/w/cpp/types/remove_cv)是一个很好的起点,它甚至有一个非常类似的例子,只不过是用指针的。 - chris
1个回答

16

remove_const仅会移除顶层的const限定符,如果有的话。在const std::string&中,const不是顶层的,因此应用remove_const对其没有影响。

当您反转顺序并先应用remove_reference时,结果类型为const string;现在const是顶层的,随后应用remove_const将移除const限定符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接