Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 类型推断如何计算表达式?_C++_Templates_Compilation - Fatal编程技术网

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!");