模板化函数如何根据类型在编译时修改它的行为?

时间:2018-03-30 01:03:58

标签: c++ templates pointers compilation

#include <iostream>
#include <vector>

class A
{
public:
   int attr;
   A(int a):attr(a){}
};

template <typename T>
int sum(std::vector<T> x)
{
  int s = 0;
  for (auto& elem : x)
  {
      s += elem.attr; // Problem is here, when elem is a pointer
  }
  return s;
}

int main()
{
   std::vector<A> x1 = {1,2,3,4,5};
   std::cout << "sum = " <<  sum(x1) << "\n";

   std::vector<A*> x2;
   for (auto& elem : x1)
     x2.push_back(&elem);

   std::cout << "sum = " <<  sum(x2) << "\n"; // Problem is this function call

   return 0;
}

由于elem.attr的{​​{1}}未定义,因此无法编译。它应该是A*

有没有办法让这项工作无需重写整个函数elem->attr

当然,sum是一个非常小的功能,但是对于更大的功能,复制粘贴长代码会开始变得有点设计问题。我本想尝试使用sum,但当然,这并不能解决问题,因为评估是在运行时而不是在编译时进行的。

1 个答案:

答案 0 :(得分:0)

您可以使用Constexpr If(自C ++ 17开始),它在编译时有效。

  

如果值为true,则抛弃statement-false(如果存在),否则抛弃statement-true。

e.g。

if constexpr (std::is_pointer_v<T>) {
    s += elem->attr; // when elem is a pointer
} else {
    s += elem.attr;  // when elem is not a pointer
}