C ++,decltype和constness错误

时间:2013-06-19 07:15:15

标签: c++

我无法理解为什么以下代码出错了。

struct A{
    typedef std::vector<std::vector<int>> Base;

    // const auto& func(std::size_t e) const
    auto func(std::size_t e) const -> decltype(std::declval<Base>()[e])
    {
            return base[e];
    }

    Base base;
};

我在gcc 4.8.1中使用上面的代码片段得到了编译错误。 (错误:类型'const value_type {aka const std :: vector}'的表达式'__gnu_cxx :: __ alloc_traits&gt;&gt; :: value_type&amp; {aka std :: vector&amp;}'类型的引用无效初始化    返回基数[e];)

请注意,如果我删除了const限定符,则可以正常工作。

但是如果我用注释的部分替换功能签名的部分(使用C ++ 14中引入的自动类型推导)。没有生成错误。 所以,我猜decltype部分是错误的。

2 个答案:

答案 0 :(得分:3)

由于Base是非const类型,std::declval<Base>()[e]指的是operator[] std::vector的非常量版本。该版本的[]返回类型为std::vector<int> &的非const引用。因此,函数的返回类型声明为decltype(std::declval<Base>()[e]),即std::vector<int> &

同时,您的成员函数func被声明为const。这意味着成员base将在该成员函数中输入const Base。这反过来意味着运算符[]base的应用将引用operator []的const版本。该版本的[]会返回const vector<int> &类型的结果。

因此,您的return语句会尝试将const vector<int> &值隐式转换为vector<int> &值。此转换无效。它违反了const-correctness规则。

在@catscradle建议中,在返回类型中添加const。或者从方法声明中删除const

auto func(std::size_t e) -> decltype(std::declval<Base>()[e])

这个或那个。

答案 1 :(得分:1)

这有效:

auto func(std::size_t e) const -> decltype(std::declval<const Base>()[e])