C++带模板可变参数构造函数的自定义Vector类无法适配initializer_list问题
问题解决方案
问题根源
- 私有
Convert实现的返回语句中额外嵌套了一层大括号,导致编译器会尝试将展开的转换后的值包装为std::initializer_list匹配构造函数,无法匹配你现有的可变参数构造或std::array构造。 - (可选优化点)使用
std::function作为回调参数存在不必要的类型擦除开销,且对可调用对象的兼容性更差。
修复方案
你不需要新增std::initializer_list构造函数,只要修改私有Convert的返回逻辑,直接将展开后的值传给现有构造函数即可,两种可行实现思路:
思路1:匹配可变参数构造函数
直接把转换后的值展开为可变参数列表,匹配你已经实现的可变参数构造函数:
public: //! Converts all values via the conversion function template <typename NewType, typename Callable> Vector<NewType, Size> Convert(Callable&& callback) const { return Convert<NewType>(std::make_index_sequence<Size>{}, std::forward<Callable>(callback)); } private: // 无回调类型转换 template <typename NewType, std::size_t ... Is> constexpr Vector<NewType, Size> Convert(std::index_sequence<Is...>) const { return Vector<NewType, Size>(static_cast<NewType>(values[Is])...); } // 带回调类型转换 template <typename NewType, typename Callable, std::size_t ... Is> Vector<NewType, Size> Convert(std::index_sequence<Is...>, Callable&& callback) const { return Vector<NewType, Size>(std::forward<Callable>(callback)(values[Is])...); }
思路2:匹配std::array构造函数
你已经实现了接受std::array的构造函数,可以先构造对应类型的std::array再返回,逻辑更直观:
public: //! Converts all values via the conversion function template <typename NewType, typename Callable> Vector<NewType, Size> Convert(Callable&& callback) const { return Convert<NewType>(std::make_index_sequence<Size>{}, std::forward<Callable>(callback)); } private: // 无回调类型转换 template <typename NewType, std::size_t ... Is> constexpr Vector<NewType, Size> Convert(std::index_sequence<Is...>) const { return std::array<NewType, Size>{static_cast<NewType>(values[Is])...}; } // 带回调类型转换 template <typename NewType, typename Callable, std::size_t ... Is> Vector<NewType, Size> Convert(std::index_sequence<Is...>, Callable&& callback) const { return std::array<NewType, Size>{std::forward<Callable>(callback)(values[Is])...}; }
验证
修改完成后你给出的测试用例可以正常编译运行,转换后的target对象三个值为1、3、4符合预期。
内容的提问来源于stack exchange,提问作者Tomáš Zato
相关产品推荐
相关产品推荐

