自定义类型允许使用std::tuple_size
和std::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...
}
答案 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 描述了类型的属性。它应该是一个类模板,它接受一个模板类型参数,以及可选的其他参数,这些参数有助于定义所描述的属性。它应该是
DefaultConstructible
,CopyConstructible
,并且直接或间接地从其 BaseCharacteristic 公开明确地派生,这是模板integral_constant
的特化,模板integral_constant
的参数由所描述的特定属性的要求决定。 BaseCharacteristic的成员名称不得隐藏,并且在UnaryTypeTrait中应明确可用。
tuple_element
的要求在[tuple.helper] / 6和[meta.rqmts] / 3中指定,但为了简洁起见,我不会在此处发布。我只想说专业化确实合法......