【发布时间】:2015-05-07 15:00:28
【问题描述】:
在成员资格测试频繁的算法中,我真的很怀念中缀 ∈ 运算符,而我喜欢使用 % 运算符。它适用于常规容器,但由于某种原因,clang 和 gcc 拒绝它用于 initializer_lists。我毫不怀疑他们是“正确的”,因为标准肯定拒绝这一点。但为什么呢?
#include <initializer_list>
#include <iostream>
#include <vector>
/// Whether e ∈ m.
template <typename T, typename U>
inline bool
in(const U& k, const std::initializer_list<T>& m)
{
return std::find(begin(m), end(m), k) != std::end(m);
}
/// Whether e ∈ m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::initializer_list<T>& m)
{
return in(k, m);
}
/// Whether e ∈ m.
template <typename T, typename U>
inline bool
operator%(const U& k, const std::vector<T>& m)
{
return in(k, m);
}
int main()
{
using strings = std::vector<std::string>;
std::cout << ("foo" % strings{"foo", "bar"}) << std::endl;
std::cout << in("foo", {"foo", "bar"}) << std::endl;
std::cout << ("foo" % {"foo", "bar"}) << std::endl; // fails
}
【问题讨论】:
-
比起
%,或许像<in>这样的named operator会更直观? -
我不讨厌运算符重载,但是整数模和集合的元素是完全不同的东西。使用普通函数而不是制造令人困惑的运算符真的有问题吗?
-
template<class T> using il<T>=std::initializer_list<T>;可以提供帮助。"foo" % il<std::string>{"foo","bar"}。这需要提及类型。 -
@deviantfan 好吧,那是因为您习惯于将
%视为仅模数,仅此而已。看到用于流的位移,您是否感到震惊? Boost 已经使用%进行序列化,或提供类似 printf 的格式。多年来,语言一直被包含在 ASCII 中,并发挥 ASCII 艺术来引入新的运算符。你不被 Haskell 的 lambda 拼写为 '\' 所困扰吗?由于∈不是ASCII,所以%是合理的,实际上是Claire编程语言中用来表示成员资格测试的字符。 -
@chris 好吧,为什么不呢,我想您指的是“命名运算符”。在这种情况下,您指的是使用
operator<和operator>玩的技巧,在这种情况下,我回到第一个问题:运算符不会在c++ 中使用initializer_lists。
标签: c++ c++11 operator-overloading initializer-list