我们有:
template <typename ...T> concept bool Numerics = ( std::is_arithmetic_v<T> && ... ) ;
template <typename T> concept bool Numeric = std::is_arithmetic_v<T>;
然后我们让编译器推导出所有数字:
template <typename T, typename U, typename V, typename W> requires Numerics<T,U,V,W>
auto foo(T arg1, U arg2, V arg3, W arg4) {
return 0.0 + arg1 + arg2 + arg3 + arg4;
}
std::cout << foo (1,2.0,3.0f,4.0l) << "\n";
编译器推导出所有类型的参数类型:
auto foo<int, double, float, long double>(int, double, float, long double):
当我们尝试将约束分配到类型说明符中以编写更短的版本时:
auto foo2(Numeric arg1, Numeric arg2, Numeric arg3, Numeric arg4) {
return 0.0 + arg1 + arg2 + arg3 + arg4;
}
虽然编译器令人惊讶地无法推断出这一点:
// err: deduction fails
//
// std::cout << foo2(1,2,3,4.0) << "\n";
似乎编译器尝试将所有类型推断为同一类型,这必须在此处失败。
为什么呢?编译器不应该能够从同一个约束中推断出不同的类型吗?
答案 0 :(得分:7)
这是概念TS中更具争议性的方面之一。当你说
#!/bin/bash
counter=1
while [ $counter -lt 999999 ]; do
number=$(printf "%07d" "$counter")
let pre_counter=counter-1
pre_numer=$(printf "%07d" "$pre_counter")
if [ ! -f ./$pre_numer.jpg ]; then
sudo fswebcam -r 1920x1080 --no-banner ./$pre_numer.jpg
else
sudo fswebcam -r 1920x1080 --no-banner ./$number.jpg
let counter=counter+1
fi;
sleep 30
done
这被翻译成好像你说过
template <typename T> concept bool C = true;
template <C T, C U>
void func(T t, U u);
但是,当您使用“缩写语法”来表示
时template <typename T, typename U> requires (C<T> && C<U>)
void func(T t, U u);
这被翻译成好像你说过
void func(C t, C u);
许多人认为这是违反直觉的,并且有proposal to change it。然而,其他人(包括Bjarne Stroustrup本人)赞成“持续演绎” - 请参阅Stroustrup的论文here。
在撰写本文时,包含在C ++ 20草案中的Concepts TS的子集不包括缩写语法。目前尚不清楚它是否会在20年结束,如果是这样,它将使用什么样的推论 - 争论仍有待解决。