无法从模板提取value_type,求助排查容器value_type提取代码问题
解决无法从容器提取value_type的问题
我来帮你搞定这个问题——你的has_push_back类型特质实现有两处关键错误,直接导致了编译时无法提取value_type的报错。
问题出在哪?
先看你写的特化代码:
template<typename C> struct has_push_back<C, std::void_t< decltype(std::declval<C>())::value_type >> : std::true_type {};
这里有两个明显的问题:
decltype(std::declval<C>())得到的是C&&(右值引用类型),你没法直接通过右值引用类型访问嵌套的value_type,正确姿势是直接访问C的嵌套类型,也就是typename C::value_type。- 更重要的是,你这个特质的目的是判断容器是否有
push_back成员函数,但现在的条件却只是检查容器有没有value_type,完全偏离了原本的意图!
正确的实现方案
我们需要重新写has_push_back,让它真正检查push_back的存在,同时确保容器具备value_type(毕竟push_back需要接收对应类型的元素)。
修正后的CustomTraits.h
#include <type_traits> // 基础模板:默认认为类型没有push_back template<typename C, typename = void> struct has_push_back : std::false_type {}; // 特化模板:同时检查两个条件 template<typename C> struct has_push_back<C, std::void_t< // 条件1:容器必须有value_type嵌套类型 typename C::value_type, // 条件2:容器必须能调用push_back,参数为value_type的右值 decltype(std::declval<C>().push_back(std::declval<typename C::value_type>())) >> : std::true_type {}; // 辅助变量模板,用起来更方便 template<typename C> inline constexpr bool has_push_back_v = has_push_back<C>::value;
调用方式调整
在MessageDecoder.h里可以这样用:
#include "CustomTraits.h" #include <type_traits> template <typename Container, typename = std::enable_if_t<has_push_back_v<Container>>> class MessageDecoder { // 你的类实现代码... };
为什么这样能解决问题?
- 我们在
std::void_t里同时做了两项检查:容器存在value_type,并且存在可以接收value_type参数的push_back成员函数。 - 这样一来,如果传入的类型没有
value_type或者没有符合要求的push_back,SFINAE机制会自动跳过这个特化模板,不会触发编译错误,而是让has_push_back_v<Container>的值为false,进而被enable_if_t过滤掉。
测试验证
你可以用下面的代码验证这个特质的正确性:
#include <vector> #include <list> #include <string> int main() { // 标准容器都支持push_back,应该返回true static_assert(has_push_back_v<std::vector<int>>); static_assert(has_push_back_v<std::list<std::string>>); // 普通数组没有push_back,返回false static_assert(!has_push_back_v<int[]>); // 自定义无push_back的类型,返回false struct NoPushBackType {}; static_assert(!has_push_back_v<NoPushBackType>); }
内容的提问来源于stack exchange,提问作者cogle
相关产品推荐
相关产品推荐

