首页 > 解决方案 > 有没有办法从`std::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 我提供了一个额外的运算符:

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)

标签: c++literalsinitializer-list

解决方案


您不能为std::initializer_list. 幸运的是,尽管 C++17 提供了一个新的非常酷的工具来帮助我们。 类模板参数推导允许我们只使用类模板的名称,编译器将确定模板参数需要是什么,因此我们不必指定它们。这意味着您可以利用std::array并且您的代码将变为

template<typename T, std::size_t N>
bool operator==(std::array<T, N> const & list, T const & ref)
{
    for(auto const& e : list)
        if (e != ref)
            return false;
    return true;
}

int main()
{
    using std::array;
    if (array{4,4,4,4,4} == 4)
        std::cout << "all 4";
}

除了 using 语句之外,它只是_litand之间的一个额外字符array


推荐阅读