C ++:std :: tuple_size / tuple_element可以专门吗?

时间:2016-11-14 08:15:35

标签: c++ c++17

自定义类型允许使用std::tuple_sizestd::tuple_element的专精吗? 我想是的,但我想绝对肯定,我找不到任何具体的信息。

示例(省略名称,成员函数和省略的get<I>重载):

template <typename T, size_t N>
struct vector { T _data[N]; };

template<size_t I, typename T, size_t N>
constexpr T& get(vector<T,N>& vec) { return vec._data[I]; }

namespace std {
template<typename T, size_t N>
class tuple_size< vector<T,N> > : public std::integral_constant<size_t, N> { };
template<size_t I, typename T, size_t N>
class tuple_element< I, vector<T,N> > { public: using type = T; };
}

我需要使用结构化绑定:

void f(vector<T,3> const& vec)
{
    auto& [x,y,z] = vec;
    // stuff...
}

1 个答案:

答案 0 :(得分:13)

用户定义类型的专业化通常很好,而且一直都是。 N4606,[namespace.std] / 1:

  

只有当声明取决于用户定义的类型且专业化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std

对于tuple_size,原始模板的要求在[tuple.helper] / 1中指定:

  

对于某些tuple_size<T>UnaryTypeTrait的所有专精都应符合BaseCharacteristic要求,integral_constant<size_t, N>N

UnaryTypeTrait,反过来,在[meta.rqmts] / 1:

  

UnaryTypeTrait 描述了类型的属性。它应该是一个类模板,它接受一个模板类型参数,以及可选的其他参数,这些参数有助于定义所描述的属性。它应该是DefaultConstructibleCopyConstructible,并且直接或间接地从其 BaseCharacteristic 公开明确地派生,这是模板integral_constant的特化,模板integral_constant的参数由所描述的特定属性的要求决定。 BaseCharacteristic的成员名称不得隐藏,并且在UnaryTypeTrait中应明确可用。

tuple_element的要求在[tuple.helper] / 6和[meta.rqmts] / 3中指定,但为了简洁起见,我不会在此处发布。我只想说专业化确实合法......