类模板内部类的类似元组的结构化绑定

Tar*_*ani 5 c++ templates inner-classes c++17 structured-bindings

我想为类模板的内部类提供结构化绑定。我怎样才能专门研究std::tuple_size这个内部类?

我无法对数据成员使用结构化绑定,因为内部类可能是与该功能不兼容的类型。所以我需要提供类似元组的结构化绑定。为了向内部类提供这样的功能,我需要部分专注std::tuple_sizenamespace 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)

Bar*_*rry 4

您不必为这种情况提供绑定: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,但提交时被拒绝了。这并不是说新提案不能做得更好。