Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何断言constexpr if else子句永远不会发生?_C++_C++17 - Fatal编程技术网

C++ 如何断言constexpr if else子句永远不会发生?

C++ 如何断言constexpr if else子句永远不会发生?,c++,c++17,C++,C++17,如果条件为true,则当constexpr的非 if constexpr(condition1){ ... } else if constexpr (condition2) { .... } else if constexpr (condition3) { .... } else { // I want the else clause never taken. But I heard the code below is not allowed static_as

如果条件为true,则当constexpr的非

if constexpr(condition1){
    ...
} else if constexpr (condition2) {
   ....
} else if constexpr (condition3) {
  ....
} else {
    // I want the else clause never taken. But I heard the code below is not allowed
    static_assert(false);
}

// I'd rather not repeat the conditions again like this:
static_assert(condition1 || condition2 || condition3);

必须使丢弃的语句依赖于模板参数

template <class...> constexpr std::false_type always_false{};

if constexpr(condition1){
    ...
} else if constexpr (condition2) {
   ....
} else if constexpr (condition3) {
  ....
} else {       
    static_assert(always_false<T>);
}
template constepr std::false_type始终_false{};
if constexpr(条件1){
...
}如果为constexpr(条件2){
....
}如果为constexpr(条件3),则为else{
....
}否则{
静态断言(始终为假);
}
这是因为

-程序格式不正确,如果需要,无需诊断

如果模板中的语句且模板未实例化,则无法为模板或
constexpr的子状态生成有效的专门化,或者

这里有一个来自的解决方法,即改用类型相关的表达式

注意:对于每个可能的专门化,丢弃的语句不能是格式错误的:

此类catch all语句的常见解决方法是类型相关的表达式,该表达式始终为false:

e、 g

template-struct-dependent\u-false:std::false\u-type{};
然后

static\u assert(dependent\u false::value);

采取稍微不同的策略

#include <ciso646>

template<auto x> void something();

template<class...Conditions>
constexpr int which(Conditions... cond)
{
    int sel = 0;
    bool found = false;
    auto elect = [&found, &sel](auto cond)
    {
        if (not found)
        {
            if (cond)
            {
                found = true;
            }
            else
            {
                ++sel;
            }
        }
    };

    (elect(cond), ...);
    if (not found) throw "you have a logic error";
    return sel;
}

template<bool condition1, bool condition2, bool condition3>
void foo()
{
    auto constexpr sel = which(condition1, condition2, condition3);
    switch(sel)
    {
        case 0:
            something<1>();
            break;
        case 1:
            something<2>();
            break;
        case 2:
            something<3>();
            break;
    }
}

int main()
{
    foo<false, true, false>();
//    foo<false, false, false>(); // fails to compile
}

真的很讽刺,因为这正是我们得到的!愚蠢的语言。如果你引用的条件依赖于模板参数,为什么它不再满足?据我所知,它仍然认为“没有有效的专业化可以产生”。看到这样的东西,我觉得在某个时候,我们应该继续种植玉米或其他东西。@AvivCohn我知道你的意思。或者可能会更进一步,最终得到一种更安全的语言?有人认为是生锈了。。。不管怎样,我希望会有一个。声称它确实不依赖于模板参数,因为它“在不同的实例化之间没有区别”,这意味着cppreference是错误的。@philipp2100它甚至不涉及安全与不安全。这是一个合理的解决方案,我们可以很好地使用它。C++有一些漂亮的部分,但其他的就像…他们在想什么?
static_assert(dependent_false<T>::value);
#include <ciso646>

template<auto x> void something();

template<class...Conditions>
constexpr int which(Conditions... cond)
{
    int sel = 0;
    bool found = false;
    auto elect = [&found, &sel](auto cond)
    {
        if (not found)
        {
            if (cond)
            {
                found = true;
            }
            else
            {
                ++sel;
            }
        }
    };

    (elect(cond), ...);
    if (not found) throw "you have a logic error";
    return sel;
}

template<bool condition1, bool condition2, bool condition3>
void foo()
{
    auto constexpr sel = which(condition1, condition2, condition3);
    switch(sel)
    {
        case 0:
            something<1>();
            break;
        case 1:
            something<2>();
            break;
        case 2:
            something<3>();
            break;
    }
}

int main()
{
    foo<false, true, false>();
//    foo<false, false, false>(); // fails to compile
}
template<class...Conditions>
constexpr int which(Conditions... cond)
{
    auto sel = 0;
    ((cond or (++sel, false)) or ...) or (throw "program is ill-formed", false);
    return sel;
}