为什么constexpr需要else才能工作? [英] Why does if constexpr require an else to work?
问题描述
我正在尝试通过以下方式使用 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屋!