【问题标题】:How do I check whether a reference is const?如何检查引用是否为 const?
【发布时间】:2018-11-23 10:07:28
【问题描述】:

我正在为我的迭代器类型编写测试,并想检查由 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

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

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

【问题讨论】:

  • 引用永远不能是 const 限定的。只有引用被引用的类型可以是 const 限定的。 std::is_const_v&lt;std::remove_reference_t&lt;T&gt;&gt;.

标签: c++ reference iterator constants typetraits


【解决方案1】:

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

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

【讨论】:

  • 它要求定义template&lt;class T&gt; constexpr bool is_const_ref_v = std::is_const_v&lt;std::remove_reference_t&lt;T&gt;&gt;;
【解决方案2】:

*it 将是引用而不是引用类型(在您的情况下,int&amp;const int&amp; 而不是 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 的 answer 更简洁,但需要 C++17。

【讨论】:

    【解决方案3】:

    is_const 始终返回 false 以供参考。相反,这样做:

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

    【讨论】:

    • is_const_vis_const 更可取吗?
    • @Flau 它只是更短。缺点是它需要 C++17。
    • @Flau _v 变体是避免写::value 的简写;同样的方式_t 避免::type
    【解决方案4】:

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

    • 注意事项

    如果 T 是引用类型,则 is_const::value 始终为 false。这 检查潜在引用类型是否存在 const-ness 的正确方法是 删除引用: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;
    }
    

    【讨论】:

    • @YSC 大声笑,我编辑了我的句子,但我认为我不想给出答案,而是想为未来的问题提供建议
    猜你喜欢
    • 1970-01-01
    • 2022-07-20
    • 1970-01-01
    • 2021-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多