【发布时间】:2019-05-18 00:29:50
【问题描述】:
我正在尝试通过以下方式使用if constexpr:
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*>());
但是编译失败
clang:
error: no matching function for call to 'binaryTraitAre_impl'
return Trait<First, Second>{}() and binaryTraitAre_impl<Trait, Rest...>();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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后错误消失了:
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?
【问题讨论】:
-
这类问题有骗人的吗?似乎
if constexpr是一个反直觉的功能,很多人都弄错了。我很确定我已经看到过这样的问题...... -
@Rakete 在 if-constexpr 标记页面中找不到一个(好吧,我只查看了第一页)。如果你找到了,我会删除我的答案。
-
@MatthieuBrucher 一样。
-
@Rakete1111 是的,我觉得我以前见过这样的问题 - 但我总是很难找到好的骗子(这就是为什么我最终求助于偏爱常见的骗子)。
-
@Barry 我现在可能会将其存储为此类重复的参考。
标签: c++ templates c++17 template-meta-programming if-constexpr