使用decltype和constness的C ++ 11尾随返回成员函数

时间:2013-11-23 23:35:43

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

我试图使用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;
}

正如评论中所提到的,只有acc()的最后一个评论版本有效,而使用其他版本,代码只会编译并打印值1

问题:我们如何使用基于acc()的新函数声明语法定义decltype函数,以便此处的编译因返回{而失败}在const &int中{1}},或换句话说,modify_const具有正确的acc()返回类型。

备注:使用const &int代替int i;作为int &i;中的成员变量会产生编译错误,正如所料。

已编辑,以便更好地区分Xv的常量。我试图强加于X::i

3 个答案:

答案 0 :(得分:5)

问题是decltype((i))返回int&并将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类型和&之间。如果您将const放入正确的位置,那么解决方案就很明显了:const should go to the right

答案 1 :(得分:0)

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

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

您的“modify_const”功能命名不正确。 i是被修改的内容,而不是const

答案 2 :(得分:0)

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

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
};

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