C++能否将std::initializer_list作为重载运算符右操作数实现in判断?
问题核心原因
你遇到的编译失败本质是引用类型不匹配:你重载的运算符参数声明的是std::initializer_list<int>&(非常量左值引用),而直接写的花括号{1,2,3,4,5}会生成一个临时的std::initializer_list对象,属于右值,C++语法不允许右值绑定到非常量左值引用上,因此编译报错。
解决方案
- 首先把所有运算符的
std::initializer_list、std::vector参数都改成const左值引用,即可支持临时对象传入。 - 由于C++语法不允许运算符右侧直接放置裸花括号列表,你可以用一个极简的宏包装
std::initializer_list构造,实现和其他语言in运算符几乎一致的使用体验。
可运行实现示例1(语法糖最贴近原生in)
#include <iostream> #include <initializer_list> #include <algorithm> // 泛型实现支持任意可比较类型 template<typename T> bool operator==(const T& val, const std::initializer_list<T>& list) { return std::find(list.begin(), list.end(), val) != list.end(); } // 语法糖宏,实现 变量 in {a,b,c} 的写法 #define in(...) == std::initializer_list{__VA_ARGS__} int main() { // 等效于其他语言的 3 in [1,2,3,4,5] std::cout << (3 in(1,2,3,4,5)) << '\n'; // 也支持传入预定义的initializer_list变量 std::initializer_list<int> il{1,2,3,4,5}; std::cout << (3 == il) << '\n'; }
可运行实现示例2(自定义<is_in>运算符版本)
#include <iostream> #include <vector> #include <initializer_list> #include <algorithm> enum { is_in }; template<typename T> T operator<(const T& lhs, decltype(is_in)) { return lhs; } // 泛型重载支持任意容器类型、任意元素类型 template<typename T, typename Container> bool operator>(const T& lhs, const Container& rhs) { return std::find(rhs.begin(), rhs.end(), lhs) != rhs.end(); } #define il(...) std::initializer_list{__VA_ARGS__} int main() { std::vector validValues{1,2,3,4,5}; // 传入容器变量 std::cout << (5 <is_in> validValues) << '\n'; // 直接传入值列表 std::cout << (5 <is_in> il(1,2,3,4,5)) << '\n'; }
内容的提问来源于stack exchange,提问作者A M
相关产品推荐
相关产品推荐

