Tar*_*ani 5 c++ templates inner-classes c++17 structured-bindings
我想为类模板的内部类提供结构化绑定。我怎样才能专门研究std::tuple_size这个内部类?
我无法对数据成员使用结构化绑定,因为内部类可能是与该功能不兼容的类型。所以我需要提供类似元组的结构化绑定。为了向内部类提供这样的功能,我需要部分专注std::tuple_size于namespace std. 问题是我得到了参数(外部类)的非推导上下文。T
我知道我可以将内部类放在全局命名空间中,从而解决每个问题,但是有什么方法可以得到相同的结果,保持类内部?
#include <tuple>
template<typename T>
class Collection
{
public:
struct Element
{
int id;
T actual_element;
};
//...
};
namespace std
{
template<typename T>
struct tuple_size<typename Collection<T>::Element> // Error! Non-deduced context
: std::integral_constant<std::size_t, 2> {};
}
//Collection iterators...
int main()
{
Collection<int> collection;
for (auto & [id, element] : collection) //what I'd like to achieve
//do some stuff...
}
Run Code Online (Sandbox Code Playgroud)
您不必为这种情况提供绑定:Element已经可以分解:
struct Element { int i, j; };
auto [i, j] = Element{2, 3}; // ok
Run Code Online (Sandbox Code Playgroud)
但是,假设Element实际上更复杂并且需要自定义绑定,那么是的 - 您将需要将其移出。但是,它不需要位于全局命名空间中。它可能在其他地方:
namespace detail {
template <typename T> struct Element { ... };
}
template<typename T>
class Collection
{
public:
using Element = detail::Element<T>;
friend Element;
// ...
};
Run Code Online (Sandbox Code Playgroud)
到那时,专门化绑定就很简单了。没有办法解决†,因为正如您所指出的,专注Collection<T>::Element于是一个非推导的上下文。
†缺少一个新的语言功能,可以让您选择加入类主体本身内的结构化绑定。有这样一篇论文,P1096,但提交时被拒绝了。这并不是说新提案不能做得更好。