如何实现类型traits判断可从std::vector取非const引用以启用容器at方法
问题产生原因
你当前的类型特征检测逻辑和实际需求不匹配:
- 你的需求是:判断
std::vector<T>的非const成员函数front()/at()的返回值可以直接绑定到T&类型的左值引用 - 但你写的检测表达式是
std::declval<U&>() = std::declval<std::vector<U>>().front(),检测的是「U&类型左值可以被std::vector<U>::front()的返回值赋值」
对于U = bool的场景,std::vector<bool>::front()返回的是代理类std::vector<bool>::reference,该类重载了隐式转换到bool的运算符,因此将其赋值给bool&类型左值是完全合法的操作,不会触发SFINAE,所以你的检测对bool也返回了true_type,不符合预期。
正确实现方案
直接检测std::vector<T>非const重载的front()返回值类型是否为T&即可,以下是兼容C++17的实现:
#include <type_traits> #include <vector> template <typename T, typename = void> struct is_ref_extractable_from_vector : std::false_type {}; template <typename T> struct is_ref_extractable_from_vector<T, std::void_t< decltype(std::declval<std::vector<T>&>().front()), std::enable_if_t<std::is_same_v<decltype(std::declval<std::vector<T>&>().front()), T&>> >> : std::true_type {}; template <typename T> inline constexpr bool is_ref_extractable_from_vector_v = is_ref_extractable_from_vector<T>::value; // 测试用例 static_assert(!is_ref_extractable_from_vector_v<bool>); static_assert(is_ref_extractable_from_vector_v<int>); static_assert(is_ref_extractable_from_vector_v<std::string>);
你可以直接把这个类型特征用到GenericContainer的at方法约束上:
template<typename T> struct GenericContainer { template <typename U = T, std::enable_if_t<is_ref_extractable_from_vector_v<U>, int> = 0> U& at(size_t index) { return data.at(index); } void append(const T& value) { data.push_back(value); } std::vector<T> data; };
内容的提问来源于stack exchange,提问作者grenouilloux
相关产品推荐
相关产品推荐

