继承std::tuple的自定义类型为何触发std::tuple_size不完整类型错误?
问题:继承std::tuple的自定义类型无法使用std::tuple_size获取元组大小
尝试获取继承自std::tuple的自定义类型type_descriptor<foo>的元组大小时,编译器报错称std::tuple_size<type_descriptor<foo>>是不完整类型,尽管struct foo和type_descriptor<foo>均已完整定义。
代码示例
#include <utility> #include <tuple> #include <cstdio> struct foo { int a_; int b_; }; template <typename T> struct type_descriptor {}; template<> struct type_descriptor<foo> : std::tuple<int, bool> { }; int main(){ printf("Size of tuple = %zu\n", std::tuple_size_v<type_descriptor<foo>>); }
报错信息
<source>:89:27: required from here /opt/compiler-explorer/gcc-12.2.0/include/c++/12.2.0/bits/utility.h:75:61: error: incomplete type 'std::tuple_size<type_descriptor<foo>>' used in nested name specifier 75 | inline constexpr size_t tuple_size_v = tuple_size<_Tp>::value; |
原因分析
std::tuple_size的标准特化仅针对std::tuple<Ts...>本身,不会自动推导或继承到派生类。你的type_descriptor<foo>是std::tuple<int, bool>的派生类,但并非std::tuple类型本身,因此标准库中没有为type_descriptor<foo>提供对应的tuple_size特化,编译器会将其视为不完整类型。
解决方法
手动为type_descriptor<foo>特化std::tuple_size,复用基类的tuple_size定义即可:
#include <utility> #include <tuple> #include <cstdio> struct foo { int a_; int b_; }; template <typename T> struct type_descriptor {}; template<> struct type_descriptor<foo> : std::tuple<int, bool> { }; // 手动特化std::tuple_size namespace std { template<> struct tuple_size<type_descriptor<foo>> : tuple_size<std::tuple<int, bool>> {}; } int main(){ printf("Size of tuple = %zu\n", std::tuple_size_v<type_descriptor<foo>>); }
如果需要适配多个继承std::tuple的type_descriptor特化,可编写通用模板特化:
namespace std { template<typename T> requires std::is_base_of_v<std::tuple<>, type_descriptor<T>> struct tuple_size<type_descriptor<T>> : tuple_size<std::remove_cvref_t<decltype(std::declval<type_descriptor<T>>())>> {}; }
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

