Cap*_*ous 8 c++ validation initializer-list constexpr c++11
我试图在编译时确定a std::initializer_list
中的所有值是否唯一.我找到了一个解决方案,以确定列表的大小,但无法将其应用于内容.我已尝试使用自由函数和构造函数,但这两种方法都导致GCC 4.7.2出现以下错误.
错误:静态断言
错误的非常量条件:'begin'不是常量表达式
我意识到std::initializer_list
没有声明成员,constexpr
但我希望有一个像尺寸验证的解决方案.是否可以使用以下内容在编译时验证内容?
#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});
}
Run Code Online (Sandbox Code Playgroud)
经过一番挖掘后,似乎在 GCC 4.7 中使用std::initializer_list
是不可能constexpr
的,因为它的声明中缺少。它应该与 GCC 4.8 一起使用,因为<initializer_list>
已更新为包含constexpr
. 不幸的是,目前无法选择使用 GCC 4.8。
如果通过引用传递衰减指针,则可以访问数组的元素。这允许根据需要进行验证,但仍然不是我希望的解决方案。以下代码是数组的可行解决方案。它仍然要求将数组的大小提供给验证函数,但很容易纠正。
#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");
}
Run Code Online (Sandbox Code Playgroud)
构建日志:
C:\Source\SwitchCaseString\main.cpp: 在函数 'int main()' 中:
C:\Source\SwitchCaseString\main.cpp:198:2: 错误:静态断言失败:设置 1 失败
C:\Source\SwitchCaseString \main.cpp:199:2: 错误:静态断言失败:设置 2 失败
C:\Source\SwitchCaseString\main.cpp:200:2: 错误:静态断言失败:设置 3 失败
C:\Source\SwitchCaseString\main .cpp:201:2: 错误: 静态断言失败: 设置 4 失败
C:\Source\SwitchCaseString\main.cpp:202:2: 错误: 静态断言失败: 设置 5 失败
C:\Source\SwitchCaseString\main.cpp :203:2: 错误: 静态断言失败: 设置 6 失败