Bon*_*ero 2 c++ c++-concepts c++20
不幸的是这段代码不起作用:
#include <iostream>
#include <type_traits>
#include <utility>
#include <tuple>
template<typename FirstArg, typename ... Args>
requires (sizeof ... (Args) == 0 || (std::is_convertible_v<Args ..., FirstArg>))
constexpr void multi_max( FirstArg firstArg, Args const &... args )
{
using namespace std;
FirstArg &max = firstArg;
auto findMax = [&]<size_t ... Is>( index_sequence<Is ...> iseq, tuple<Args ...> tArgs )
{
((max = get<Is>( tArgs ) > max ? get<Is>( tArgs ) : max), ...);
};
findMax( make_index_sequence<sizeof ... (Args)>(), make_tuple( args ... ) );
}
int main()
{
multi_max( 1 );
//multi_max( 1, 2, 3 );
}
Run Code Online (Sandbox Code Playgroud)
注释部分不满足要求约束的右半部分。为什么 ?如果我删除第一个约束,编译器会抱怨将参数错误地解包到元组中。
查看编译器错误的相关部分:
注意:因为替换的约束表达式格式错误:变量模板“is_convertible_v”的模板参数太多
你正在使用is_convertible_v<int, int, int>. 您想要的是各个参数的所有测试都为 true,您可以使用折叠表达式来完成此操作:
requires (sizeof ... (Args) == 0 || (std::is_convertible_v<Args, FirstArg> && ...))
Run Code Online (Sandbox Code Playgroud)
然而,对于 0 个元素的包,折叠表达式将生成truefor &&,因此第一部分现在是多余的:
requires (std::is_convertible_v<Args, FirstArg> && ...)
Run Code Online (Sandbox Code Playgroud)
清理以使用该概念convertible_to而不是旧的类型特征:
requires (std::convertible_to<Args, FirstArg> && ...)
Run Code Online (Sandbox Code Playgroud)
现在事情看起来有点令人怀疑的方便。我们实际上可以将其移至模板参数并完全摆脱requires:
template<typename FirstArg, std::convertible_to<FirstArg> ... Args>
Run Code Online (Sandbox Code Playgroud)
该占位符将FirstArg作为第二个参数插入,并将给定类型作为第一个参数,因此给定的类型T将测试std::convertible_to<T, FirstArg>。
| 归档时间: |
|
| 查看次数: |
1957 次 |
| 最近记录: |