C++ 类型推断如何计算表达式?
我只是用模板做了一个钳制函数。看起来是这样的:C++ 类型推断如何计算表达式?,c++,templates,compilation,C++,Templates,Compilation,我只是用模板做了一个钳制函数。看起来是这样的: template <typename Tp_, typename Up_, typename Vp_> inline auto clamp(Tp_ x, Up_ xmin, Vp_ xmax) noexcept -> decltype(x < xmin ? xmin : (x > xmax ? xmax : x)) { return x < xmin ? xmin : (x > xmax ? xmax
template <typename Tp_, typename Up_, typename Vp_>
inline auto clamp(Tp_ x, Up_ xmin, Vp_ xmax)
noexcept -> decltype(x < xmin ? xmin : (x > xmax ? xmax : x)) {
return x < xmin ? xmin : (x > xmax ? xmax : x);
}
template <typename Tp_, typename Up_>
inline auto clamp(Tp_ x, const Up_ &v) -> decltype(clamp(x, min(v),
max(v))) {
static_assert(is_iterable<Up_>::value,
"The data set must be iterable");
return clamp(x, min(v), max(v));
}
但是当我考虑它的时候,那就没有意义了:decltype(clamp(x,min(v),max(v)))
的结果在运行时之前是不应该知道的,是吗
以防万一,我尝试用一些变量数据替换我的测试:
TEST(StatsTest, clamp) {
int a = 0;
float b = 65.3f;
double c = 89.7;
ASSERT_EQ(clamp(a, b, c), 65.3f);
}
但它还是过去了
解释是什么?clamp返回的类型是参数的常见类型,而不是所选参数的类型 然后,你被进一步的晋升所愚弄,使你的平等检查保持不变
decltype(true?7:3.0)
的类型与decltype(false?7:3.0)
一般情况下,您不能这样做。这种方法在这种情况下有效的唯一原因是,您使用的是具有默认转换的整数/浮点值。例如:
float f;
int y;
double z;
std::cin >> f;
std::cin >> y;
std::cin >> z;
auto p = clamp(f, y, z);
static_assert(std::is_same<decltype(p), double>::value, "Not Double!");
float f;
int-y;
双z;
标准:cin>>f;
标准:cin>>y;
std::cin>>z;
自动p=夹紧(f,y,z);
静态断言(std::is_same::value,“notdouble!”);
这将起作用,因为所有给定的类型都可以升级为
double
。通常,如果您尝试对没有这样提升的类型执行此操作,您将得到编译时错误,因为函数的返回类型必须在编译时已知(当然必须知道,否则编译器如何知道在堆栈上为返回值分配多少空间?).decltype
是一个编译时运算符。它必须在运行前就知道。@chris这是我的观点,编译器如何知道这样一个表达式的结果?如果它能推导出这个表达式的类型,在我看来它能推导出所有表达式的类型。。。或者至少所有表达式(如IF,OR,LT,GT等)类型不能依赖于C++中的运行时值。语言规则禁止这样做。这意味着无论测试是真是假,条件表达式的结果都是相同的。是的,所有表达式都有一个编译时类型。有一组相当复杂的规则来控制条件表达式的类型,这是根据其参数的类型计算出来的。
float f;
int y;
double z;
std::cin >> f;
std::cin >> y;
std::cin >> z;
auto p = clamp(f, y, z);
static_assert(std::is_same<decltype(p), double>::value, "Not Double!");