如何检查引用是否为 const?

How do I check whether a reference is const?

我正在为我的迭代器类型编写测试,并想检查 begin()cbegin() 提供的取消引用迭代器返回的引用分别是非常量和常量。

我尝试做类似以下的事情:-

#include <type_traits>
#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec{0};

    std::cout << std::is_const<decltype(*vec.begin())>::value << std::endl;
    std::cout << std::is_const<decltype(*vec.cbegin())>::value << std::endl;
}

但这两种情况都会打印 0

有没有办法检查引用是否为常量?

我可以使用 C++11/14/17 功能。

删除引用以获取引用类型以检查其常量性。引用本身永远不是 const - 即使对 const 的引用通俗地称为 const 引用:

std::is_const_v<std::remove_reference_t<decltype(*it)>>

*it 将是引用而不是引用类型(int&const int& 而不是 intconst int 在您的情况下)。因此,您需要删除引用:

#include <iostream>
#include <type_traits>
#include <vector>

int main() {
    std::vector<int> vec{0};

    std::cout << std::is_const<std::remove_reference<decltype(*vec.begin())>::type>::value << std::endl;
    std::cout << std::is_const<std::remove_reference<decltype(*vec.cbegin())>::type>::value << std::endl;
}

这会产生:

0
1

注:以上作品使用C++11。 @eerorika 的 更简洁,但需要 C++17。

is_const总是returnsfalse供参考。相反,做:

std::is_const_v<std::remove_reference_t<decltype(*v.begin() )>> // false
std::is_const_v<std::remove_reference_t<decltype(*v.cbegin())>> // true

您可以在此处查看文档注释: https://en.cppreference.com/w/cpp/types/is_const

  • 备注

If T is a reference type then is_const::value is always false. The proper way to check a potentially-reference type for const-ness is to remove the reference: is_const::type>.

for(auto it=vec.begin(); it!=vec.end(); ++it) {
    std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
}

for(auto it=vec.cbegin(); it!=vec.cend(); ++it) {
    std::cout << std::is_const<std::remove_reference<decltype(*it)>::type>::value << std::endl;
}