首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在编译时验证std::initializer_list的内容

在编译时验证std::initializer_list的内容
EN

Stack Overflow用户
提问于 2013-05-25 04:57:39
回答 1查看 2.1K关注 0票数 8

我试图在编译时确定std::initializer_list中的所有值是否都是唯一的。我能够找到列表中的valiate the size的解决方案,但无法将其应用于内容。我尝试了自由函数和构造函数,但这两种方法都导致了GCC 4.7.2的错误。

错误:静态断言的非常数条件 错误:“开始”不是一个常量表达式

我意识到std::initializer_list的成员没有被声明为constexpr,但我希望有一个类似于大小验证的解决方案。是否可以在编译时使用以下内容来验证内容?

代码语言:javascript
运行
复制
#include <initializer_list>

template<typename InputIterator>
constexpr bool Validate(InputIterator begin, InputIterator end)
{
    static_assert(*begin == *end, "begin and end are the same");
    //  The actual implemetnation is a single line recursive check.
    return true;
}

template<typename InputType>
constexpr bool Validate(const std::initializer_list<InputType>& input)
{
    // "-1" removed to simplify and eliminate potential cause of error
    return Validate(input.begin(), input.end() /* - 1 */);
}

int main()
{
    Validate({1, 2, 1});
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-05-25 09:55:48

经过一番挖掘,看来在GCC 4.7中不可能使用std::initializer_list,因为它的声明中缺少constexpr。它应该与GCC 4.8合作,因为<initializer_list>已经被更新,包括了constexpr。不幸的是,目前不能选择使用GCC 4.8。

但是,如果通过引用传递衰减指针,则可以访问数组的元素。这允许验证按需要进行,但仍然不是我所希望的解决方案。下面的代码是数组的可行解决方案。它仍然要求将数组的大小提供给验证函数,但它很容易纠正。

代码语言:javascript
运行
复制
#include <initializer_list>

template<typename T>
constexpr bool Compare(T& data, int size, int needleIndex, int haystackIndex)
{
    return
        needleIndex == haystackIndex ?
            Compare(data, size, needleIndex + 1, haystackIndex)
        :   needleIndex == size ?
                false
            :   data[needleIndex] == data[haystackIndex] ?
                    true
                :   Compare(data, size, needleIndex + 1, haystackIndex);
}

template<typename T>
constexpr bool Compare(T& data, int size, int index)
{
    return
        index == size ?
            false
        :   Compare(data, size, index + 1) ?
                true
            :   Compare(data, size, 0, index);
}


template<typename T, int ArraySize>
constexpr bool Validate(T(&input)[ArraySize], int size)
{
    return !Compare(input, size, 0);
}

int main()
{
    constexpr int initData0[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    constexpr int initData1[] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    constexpr int initData2[] = {2, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    constexpr int initData3[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 8};
    constexpr int initData4[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 7};
    constexpr int initData5[] = {0, 1, 0, 3, 4, 5, 6, 7, 8, 9};
    constexpr int initData6[] = {0, 1, 2, 3, 4, 5, 6, 9, 8, 9};

    static_assert(Validate(initData0, 10), "set 0 failed"); // <-- PASS
    static_assert(Validate(initData1, 10), "set 1 failed"); // <-- (and below) FAIL
    static_assert(Validate(initData2, 10), "set 2 failed");
    static_assert(Validate(initData3, 10), "set 3 failed");
    static_assert(Validate(initData4, 10), "set 4 failed");
    static_assert(Validate(initData5, 10), "set 5 failed");
    static_assert(Validate(initData6, 10), "set 6 failed");
}

构建日志:

C:\Source\SwitchCaseString\main.cpp:在函数'int ()‘中: C:\Source\SwitchCaseString\main.cpp:198:2:错误:静态断言失败: set 1失败 C:\Source\SwitchCaseString\main.cpp:199:2:错误:静态断言失败: set 2失败 C:\Source\SwitchCaseString\main.cpp:200:2:错误:静态断言失败: set 3失败 C:\Source\SwitchCaseString\main.cpp:201:2:错误:静态断言失败: set 4失败 C:\Source\SwitchCaseString\main.cpp:202:2:错误:静态断言失败: set 5失败 C:\Source\SwitchCaseString\main.cpp:203:2:错误:静态断言失败: set 6失败

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/16746564

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档