【问题标题】:C++11 trailing return member function using decltype and constness使用 decltype 和 constness 的 C++11 尾随返回成员函数
【发布时间】:2013-11-23 23:35:43
【问题描述】:

我正在尝试使用 decltype 了解 C++11 中基于尾随返回的新函数声明语法。

在下面的代码中,我试图定义一个返回 const & 的成员函数,以允许对i 进行只读访问

#include <iostream>
#include <type_traits>

struct X {
    int &i;

    X(int &ii) : i(ii) {}

//    auto acc() const -> std::add_const<decltype((i))>::type { return i; } // fails the constness test
    auto acc() const -> decltype(i) { return i; } // fails the constness test
//    const int &acc() const { return i; } // works as expected   
};

void modify_const(const X &v) {
    v.acc() = 1;
}

int main() {
    int i = 0;
    X x(i);

    modify_const(x);
    std::cout << i << std::endl;

    return 0;
}

如 cmets 中所述,只有最后一个注释版本的 acc() 有效,而使用其他代码,代码只是编译并打印值 1

问题:我们如何使用基于decltype的新函数声明语法来定义acc()函数,使得这里的编译由于在@中返回const &amp;int而失败987654328@,或者换句话说,acc() 有一个正确的const &amp;int 返回类型。

备注:使用int i; 而不是int &amp;i; 作为X 中的成员变量会产生编译错误,正如预期的那样。

编辑以更好地区分 vX::i 的常量。我试图在acc() 中强加后者。

【问题讨论】:

    标签: c++ c++11 constants decltype type-deduction


    【解决方案1】:

    问题是decltype((i)) 返回int&amp; 并将const 应用于该类型没有效果。你想要类似的东西

    template <typename T> struct add_ref_const { typedef T const type; };
    template <typename T> struct add_ref_const<T&> { typedef T const& type; };
    

    ...然后使用

    auto acc() const -> typename add_ref_const<decltype((i))>::type { return i; }
    

    也就是说,const 需要介于 T&amp; 类型之间。如果您将const 放入正确的位置:const should go to the right,则解决方案会很明显。

    【讨论】:

    • 在这种特殊情况下也有效的是auto acc() const -&gt; decltype(i) const&amp; { return i; } 我只是想知道实现它的正确方法是什么,因为您的建议需要额外的特征支持。这很好,但为什么 add_ref_const 结构首先在 std 库中不可用?
    【解决方案2】:

    const 成员函数修改指向非常量的指针的目标没有任何违法行为,即使该指针是从成员变量中获取的。

    从编译器的角度来看,int&amp; 是正确的返回类型。

    您的“modify_const”函数命名不正确。 i 是被修改的,而不是 const

    【讨论】:

    • 我明白你的意思,我编辑了我的帖子以更清楚地表明我的目标实际上是对i 拥有只读访问权限
    【解决方案3】:

    只需在左侧添加一个 & 并跳过尾随返回类型。

    struct X {
        int &i;
    
        X(int &ii) : i(ii) {}
    
        auto& acc() const { return i; } // Returns const reference
        auto& acc() { return i; } // Returns non-const reference
        const auto& acc() const { return i; } // Add const to the left to make it even more readable
    };
    

    请注意,使用此语法,您可以在声明函数后声明成员变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-07
      • 2017-08-02
      • 2019-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多