c++ - 有没有办法从 `std::initializer_list` 创建用户定义的文字?

标签 c++ literals initializer-list

就像主题中一样:有没有办法从 std::initializer_list 创建用户定义的文字? ?

我正在尝试做类似的事情:

template <typename T> inline
std::initializer_list<T> const & operator "" _lit(std::initializer_list<T> const & list)
{
    return std::move(list); // I am not sure, but this line might cause undefined behavior... well I'll think about it latter...
}

int main()
{
    { 10, 20, 30, 40 }_lit // Error: identifier '_lit' is undefined;

    return 0;
}

但编译器似乎不理解我正在尝试调用 operator""_lit({10, 20, 30, 40});有什么办法可以解决吗?


编辑:
对不起,原来这只是XY问题的另一个例子……
让我详细说明

我正在尝试“扩展”当前的 C++ 语法(这是一个有趣的小项目...)

主要思想是简化这个:

if ((val_1 == value) && (val_2 == value) && (val_3 == value)) { /* ... */ }

进入一些事情:

if (std::initializer_list<T>{val_1, val_2, val_3} == value)

ofc 我正在提供额外的运算符(operator):

template <typename T> inline
bool operator==(std::initializer_list<T> const & list, T const & ref)
{
    for (auto const & element : list)
    {
        if (element == ref) { /* Do nothing. */ }
        else
        {
            return false;
        }
    }
    return true;
}

一切都会很好,但我不喜欢输入 std::initializer_list<T>在花括号前...否则,编译器会选择默认版本 operator==()我得到一个编译错误...

文字来这里是为了改变 if (std::initializer_list<T>{val_1, val_2, val_3} == value)进入if ({val_1, val_2, val_3}_lit == value)

最佳答案

template<class T, std::size_t N>
struct any_of:std::array<T, N> {
  #define MAKE_OPERATOR( OPERATOR ) \
    template<class U, \
      std::enable_if_t< std::is_same<void, std::void_t< \
        decltype( std::declval<T const&>() == std::declval<U const&>() ) \
      >>{}, bool> =true \
    > \
    friend bool operator OPERATOR ( any_of const& lhs, U const& rhs) { \
      return std::any_of( \
        lhs.begin(), lhs.end(), \
        [&](auto&& lhs){ return lhs OPERATOR rhs; } \
      ); \
    } \
    template<class U, \
      std::enable_if_t< std::is_same<void, std::void_t< \
        decltype( std::declval<U const&>() == std::declval<T const&>() ) \
      >>{} && !std::is_same< U, any_of >{} , bool> =true \
    > \
    friend bool operator OPERATOR ( U const& lhs, any_of const& rhs) { \
      return std::any_of( \
        rhs.begin(), rhs.end(), \
        [&](auto&& rhs){ return lhs OPERATOR rhs; } \
      ); \
    }
  MAKE_OPERATOR(==)
  MAKE_OPERATOR(!=)
  MAKE_OPERATOR(<)
  MAKE_OPERATOR(<=)
  MAKE_OPERATOR(>=)
  MAKE_OPERATOR(>)
  #undef MAKE_OPERATOR
  explicit any_of( std::array<T, N> arr):std::array<T, N>(std::move(arr)) {}
  template<class...Ts>
  explicit any_of( T t, Ts... ts ):std::array<T, N>{ std::move(t), std::move(ts)... } {}
  any_of( any_of const& )=delete;
  any_of& operator=( any_of const& )=delete;
  any_of()=delete;
};
template<class T, std::size_t N>
any_of(T(&)[N]) -> any_of<T,N>;
template<class T, class...Ts>
any_of(T, Ts...) -> any_of<T, 1+sizeof...(Ts)>;

测试代码:

if (any_of{1,2,3} == 2) {
    std::cout << "2 is there\n";
}
if (! (any_of{1,2,3} == 7) ){
    std::cout << "7 is not there\n";
}

if (any_of{1,2,3} == any_of{5,6,1}) {
    std::cout << "overlap!\n";
}
if (!(any_of{1,2,3} == any_of{5,6,7})) {
    std::cout << "no overlap!\n";
}

Live example .

输出 编译器:

2 is there
7 is not there
overlap!
no overlap!

支持各种比较运算符。

跨型双any_of,如:

any_of{1,2,3} == any_of{3.14, 5.7, 1.0}

将无法编译,因为 any_of== 都有效。

关于c++ - 有没有办法从 `std::initializer_list` 创建用户定义的文字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53819931/

相关文章:

c++ - 替代初始化唯一指针的 vector

如果结构体包含互斥锁,则 C++ 将初始值设定项列表推送到标准 vector 时出现问题

c++ - opencv 和 Matlab 的 Sobel 滤波器输出不同

c++ - 在 C++ 中流式传输字符串文字

python - 为什么 Python 3 允许 "00"作为 0 的文字,但不允许 "01"作为 1 的文字?

java - 为什么我们需要 (HEX | OCT)_to_DEC 方法?

c++ - std::initializer_list 返回值的生命周期

c++ - 用于捕获线程 CPU 时间的 API

c++ - "Using"类内指令

c++ - 如果运算符删除没有实现,为什么不能编译