在类上启用std :: get支持

Mat*_*son 10 c++ c++11 stdtuple

我必须专门支持std :: get的模板是什么?

struct MyClass {
  int a;
};

template <const size_t I>
struct MyContainer {
  MyClass array[I];
};
Run Code Online (Sandbox Code Playgroud)

我有什么专业能够做到的:

MyContainer<16> mc;
std::get<0>(mc);
Run Code Online (Sandbox Code Playgroud)

eca*_*mur 14

std::get不是标准库的自定义点; (三个函数模板重载pair,tuplearray)没有明确允许用户自定义的过载,因此17.6.4.2.1p1适用,添加自己的函数模板重载的声明是未定义的行为.

请注意,get作为非限定名称从C++ 17开始的自定义点; 结构化绑定声明协议使用它来访问类似元组的元素; 但这是一个不合格的名字,而不是合格的名字std::get.

这就是说,如果你这样写:

namespace std {
   template<size_t I, size_t N> MyClass &get(MyContainer<N> &c) { return c.array[I]; }
}
Run Code Online (Sandbox Code Playgroud)

类似地,对于rvalue引用和const引用重载,您的程序可能会按预期工作.

然而,标准已经提供了很少的观点array:

template<size_t N> using MyContainer = std::array<MyClass, N>;
Run Code Online (Sandbox Code Playgroud)

  • 这在 C++17 中没有改变,以便用户可以通过利用 _"`get&lt;i&gt;(e)` 的查找使他们自己的类使用结构化绑定,其中 get 是通过参数相关查找来查找的“_?参见 [cppreference](http://en.cppreference.com/w/cpp/language/structured_binding),案例 2 (3认同)
  • @underscore_d的问题在于get &lt;0&gt;(e)不使用依赖于参数的查找,因为&lt;0&gt;阻止ADL工作。(请参阅https://godbolt.org/z/YIEa-c。这在C ++ 20中已修复,如您所见,可以通过在该Godbolt链接中将c ++ 17更改为c ++ 2a来看到。) (3认同)
  • @underscore_d 不完全是;那是 `get` 作为非限定名称,而不是限定名称 `std::get`。不过,这是很重要的一点;谢谢! (2认同)