C++ C++;:std::tuple\u size/tuple\u元素可以专门化吗?

C++ C++;:std::tuple\u size/tuple\u元素可以专门化吗?,c++,c++17,C++,C++17,自定义类型是否允许专门化std::tuple\u大小和std::tuple\u元素? 我想是的,但我想绝对肯定,我找不到任何具体的信息 示例(省略名称空间、成员函数和get重载): 模板 结构向量{T_数据[N];}; 模板 constexpr T&get(vector&vec){return vec._data[I];} 名称空间标准{ 模板 类tuple_size:公共std::integral_常量{}; 模板 类tuple_元素{public:使用type=T;}; } 我需要它用于结

自定义类型是否允许专门化
std::tuple\u大小
std::tuple\u元素
? 我想是的,但我想绝对肯定,我找不到任何具体的信息

示例(省略名称空间、成员函数和
get
重载):

模板
结构向量{T_数据[N];};
模板
constexpr T&get(vector&vec){return vec._data[I];}
名称空间标准{
模板
类tuple_size:公共std::integral_常量{};
模板
类tuple_元素{public:使用type=T;};
}
我需要它用于结构化绑定:

void f(vector<T,3> const& vec)
{
    auto& [x,y,z] = vec;
    // stuff...
}
void f(向量常量和向量)
{
自动&[x,y,z]=vec;
//东西。。。
}

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

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

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

对于某些
N
而言,
tuple\u size
的所有专门化应满足
unarytypetracit
要求,且
BaseCharacteristic
integral\u常量

unarytypetracit
,依次在[meta.rqmts]/1中:

UnaryTypeTrait描述类型的属性。它应该是一个类模板,它接受一个模板类型参数,以及(可选)帮助定义所描述属性的附加参数。它应该是可默认构造的、可复制的,并且直接或间接地从其基本特征公开、明确地派生出来,基本特征是模板积分常数的特化,模板
积分常数的参数由所描述的特定属性的要求确定。BaseCharacteristic的成员名称不得隐藏,且应在UnaryTypeTrait中明确可用


tuple\u元素
的要求在[tuple.helper]/6和[meta.rqmts]/3中指定,但为了简洁起见,我不会在这里发布它们。只需说,专门化…确实是合法的。

请注意,在C++1z中使用新的
auto[a,b,C]
结构化绑定功能需要这样做。有没有办法根据基类或公共接口来定义这些功能?我有很多
F~=tuple
G~=tuple
,等等,如果它们是tuple的子类,我仍然需要定义
tuple\u元素:tuple\u元素
等等。我所能想到的就是打开通用的
tuple\u size
/
tuple\u元素
来使用
size()
或基类,这似乎是自找麻烦。如果我不能做得更好,我就只能使用宏了。@John:有趣的是,我昨天也碰到了同样的问题。:-]不幸的是,我没有想出任何不需要对特征进行微小的干扰性改变的方法,但是我控制了所讨论的特征,所以我没有想太多。我很想知道是否有一个聪明的非侵入性解决方案@约翰:这里有一个想法,使用C++20:我想不出一个没有概念的方法来实现非侵入性(例如,对于结构化绑定),所以C++17代码可能不走运。非常感谢!C++20看起来很疯狂。我的一次尝试是有效的
模板结构元组大小:…
,但遗憾的是无法推导出T。我想这就是概念的意义所在。快速提问,使用
is\u base\u of
,这不是用来避免误判的
可转换技术吗?为什么两者同时使用?
void f(vector<T,3> const& vec)
{
    auto& [x,y,z] = vec;
    // stuff...
}