概念 return 类型要求语法二对一模板参数

concepts return type requirement syntax two versus one template parm

我想知道 std::same_as 是如何定义的以及我们如何在概念或要求中使用它。

示例:

void f1() { } 
bool f2() { return true; }

template < typename T>
void Do( T func )
{
    if constexpr ( requires { { func() } -> std::same_as<bool>; } ) 
    {   
        std::cout << "Func returns bool " << std::endl;
    }   

    if constexpr ( requires { { func() } -> std::same_as<void>; } ) 
    {   
        std::cout << "Func returns void " << std::endl;
    }   
}

int main()
{
    Do( f1 );
    Do( f2 );
}

按预期工作。

但是如果我查看 std::same_as 的定义,我会找到一个可能的实现:

namespace detail {
    template< class T, class U >
    concept SameHelper = std::is_same_v<T, U>;
}
 
template< class T, class U >
concept same_as = detail::SameHelper<T, U> && detail::SameHelper<U, T>;

让我感到奇怪的是,在那种情况下我看到了两个模板参数 TU,而我们只需要写一个像 { { func() } -> std::same_as<bool>; }.

在那种情况下,{ { func() } -> std::same_as<bool>; } 会被转换为 std::same_as<magic_return_type, bool> 是某种 魔法 吗?

A concept 通常类似于 constexpr inline bool 变量模板。但是,它确实具有特殊属性。关于这道题,第一个模板参数是类型的concept是一种特殊的概念:“类型概念”。

在某些位置,可以在没有第一个模板参数的情况下使用类型概念。在那些地方,第一个参数将根据它的使用方式推导。

requires表达式的复合要求中,类型概念是跟在->后面的。 The first parameter of the concept will be filled in by the type of the expression E in the {}, as if by decltype((E)).