c++ - 在只读(即 const)访问器上执行结构化绑定(bind)的最佳实践是什么?

标签 c++ c++17 structured-bindings

考虑以下类 foo:

class foo {
private:
    int x = 0;
    int y = 0;

public:
    template <std::size_t I>
    int const& get() const
    {
        if constexpr (I == 0) {
            return x;
        }
        else return y;
    }
};

我想为 foo 实现结构化绑定(bind),所以我添加了以下内容:

namespace std {
    template <>
    struct tuple_size<foo> : std::integral_constant<std::size_t, 2u> {};

    template <std::size_t I>
    struct tuple_element<I, foo> {
        using type = int;
    };
}

现在,如果用户要执行结构绑定(bind),他/她必须明确添加一个 const 限定符:

int main() {
    foo f;
    auto [a, b] = f;            // Won't compile
    auto& [x, y] = f;           // Won't compile
    const auto [c_a, c_b] = f;  // Compiles
    const auto& [c_x, c_y] = f; // Compiles
    return 0;
}

(因为我们无法将 int& 绑定(bind)到 int const&)

或者,我可以将 tuple_element 类型定义为 const int。现在所有四个语句都可以编译:

namespace std {
    template <>
    struct tuple_size<foo> : std::integral_constant<std::size_t, 2u> {};

    template <std::size_t I>
    struct tuple_element<I, foo> {
        using type = const int;         // <=== const added here
    };
}

int main() {
    foo f;
    auto [a, b] = f;            // Compiles
    auto& [x, y] = f;           // Compiles
    const auto [c_a, c_b] = f;  // Compiles
    const auto& [c_x, c_y] = f; // Compiles
    return 0;
}

现在请注意,即使它们的声明中没有 const 限定符,abxy 都是int const。这可能会让用户感到困惑。

所以我的问题是:以上哪一项被认为是更好的做法?

最佳答案

So my question is: which one of the above is considered a better practice?

更喜欢第二种方法来尝试模仿内置和标准发生的情况:

class foo {
public:
    const int x = 0;
    const int y = 0;
};

int main() {
    foo f;
    auto [a, b] = f;            // Compiles
    auto& [x, y] = f;           // Compiles
    const auto [c_a, c_b] = f;  // Compiles
    const auto& [c_x, c_y] = f; // Compiles
}

来自binding_a_tuple-like_type

std::tuple<float&,char&&,int> tpl(x,std::move(y),z);
const auto& [a,b,c] = tpl;
// a names a structured binding that refers to x; decltype(a) is float&
// b names a structured binding that refers to y; decltype(b) is char&&
// c names a structured binding that refers to the 3rd element of tpl; decltype(c) is const int

关于c++ - 在只读(即 const)访问器上执行结构化绑定(bind)的最佳实践是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59452510/

相关文章:

android - 使用不同于 Application.mk 中定义的 STL 编译 android-ndk 模块

c++ - 为什么std::assoc_laguerre的第二个参数是unsigned int?

c++ - 如何为 std::tuple 包装器类启用结构化绑定(bind)?

c++ - 转换参数包类型

c++ - 允许模板化类的结构化绑定(bind)

c++ - Lambda 隐式捕获因从结构化绑定(bind)声明的变量而失败

c++ - 如何从可变数量的 STL vector 创建变量的所有排列

c++ - C 和 C++ 的数组大小声明差异

c++ - 查找最接近质心的几何内部点

c++ - 在内联匿名命名空间中声明的全局命名空间中定义模板函数时 undefined reference