c++ - 类型推导如何用于评估表达式?

标签 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 : 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));
}

我有一个单元测试来测试执行此操作的函数:

TEST(StatsTest, clamp) {
  ASSERT_EQ(clamp(1, 0, 5), 1);
  ASSERT_EQ(clamp(-1, 0, 3), 0);
  ASSERT_EQ(clamp(15, 0, 3), 3);

  ASSERT_EQ(clamp(1, 0.f, 3.), 1);
  ASSERT_EQ(clamp(-1, 0.f, 3.), 0.f);
  ASSERT_EQ(clamp(15, 0, 3), 3.);

  ASSERT_EQ(clamp(543, v1), 543);
  ASSERT_EQ(clamp(-143, v1), 71);
  ASSERT_EQ(clamp(14143, v1), 977);
}

但是当我考虑它时,这没有意义: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 ) 类型相同。

关于c++ - 类型推导如何用于评估表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32085717/

相关文章:

c++ - 如何在C++中调用cygwin?

c++ - QFontMetrics boundingRect

c++ - 引用模板类型的赋值运算符需要非常量重载

java - Fedora 25 - 拒绝识别 Java JDK,$JAVA_HOME 似乎是正确的

c++ - 删除这个第二次复制操作可以忽略不计

compilation - 用gradle的想法编译

c++ - 使用 Boost 库时如何在 C++ 中覆盖 new?

c++ - 从 vector 列表中删除 vector 元素 C++

C++ 枚举类作为可变模板参数

asp.net-mvc - 让 SubSonic MVC 模板与我的数据库一起使用