为什么constexpr需要else才能工作? [英] Why does if constexpr require an else to work?

查看:84
本文介绍了为什么constexpr需要else才能工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过以下方式使用 if constexpr

I am trying to use if constexpr in the following way:

template<template <typename First, typename Second> class Trait,
    typename First, typename Second, typename... Rest>
constexpr bool binaryTraitAre_impl()
{
    if constexpr (sizeof... (Rest) == 0)
    {
        return Trait<First, Second>{}();    
    }
    return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
}

示例用例:

static_assert(binaryTraitAre_impl<std::is_convertible,
    int, int&,
    int*, void*>());

但这无法编译

error: no matching function for call to 'binaryTraitAre_impl'
        return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
                                            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~



gcc



gcc:

prog.cc: In instantiation of 'constexpr bool binaryTraitAre_impl() [with Trait = std::is_convertible; First = int*; Second = void*; Rest = {}]':
prog.cc:9:80:   required from 'constexpr bool binaryTraitAre_impl() [with Trait = std::is_convertible; First = int; Second = int&; Rest = {int*, void*}]'
prog.cc:15:83:   required from here
prog.cc:9:80: error: no matching function for call to 'binaryTraitAre_impl<template<class _From, class _To> struct std::is_convertible>()'
    9 |         return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
      |                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
prog.cc:3:17: note: candidate: 'template<template<class First, class Second> class Trait, class First, class Second, class ... Rest> constexpr bool binaryTraitAre_impl()'
    3 |  constexpr bool binaryTraitAre_impl()
      |                 ^~~~~~~~~~~~~~~~~~~
prog.cc:3:17: note:   template argument deduction/substitution failed:
prog.cc:9:80: note:   couldn't deduce template parameter 'First'
    9 |         return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
      |                                             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~

但是我发现一旦添加 else ,错误就会消失:

But I found the error goes away once I add else:

template<template <typename First, typename Second> class Trait,
    typename First, typename Second, typename... Rest>
constexpr bool binaryTraitAre_impl()
{
    if constexpr (sizeof... (Rest) == 0)
    {
        return Trait<First, Second>{}();
    }
    else
    {
        return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
    }
}

实时演示

发生了什么?在这种情况下,编译器为什么不能推断 else

What happened? Why can the compiler not infer the else in this case?

推荐答案

这是来自 constexpr if 的cppreference的摘录:

This is the excerpt from cppreference on constexpr if:


Constexpr如果
以if constexpr开头的语句称为constexpr if语句。

Constexpr If The statement that begins with if constexpr is known as the constexpr if statement.

在constexpr if语句中,condition的值必须是类型经过上下文转换的常量表达式布尔如果值是true,则丢弃statement-false(如果存在),否则,丢弃statement-true。

In a constexpr if statement, the value of condition must be a contextually converted constant expression of type bool. If the value is true, then statement-false is discarded (if present), otherwise, statement-true is discarded.

很明显,两个分支中只有一个被丢弃。对于您来说,罪魁祸首代码不能被丢弃,因为它位于 else 子句之外。

It is clear that only one of the two branches is discarded. In your case, the culprit code cannot be discarded because it's outside the else clause.

这篇关于为什么constexpr需要else才能工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆