模板专业化还是条件表达式?

时间:2012-07-01 19:35:23

标签: c++ templates specialization open-closed-principle

我深入研究了一个新项目,我用一堆模板和专业来解决这个问题。现在,在没有编程的一天之后,我发现自己在询问是否真的值得额外的代码行。

问题是:专业化有哪些优势?

这是:

template <int i> class A {};
template <> class A <1> { void foo() {/* something */}  };
template <> class A <2> { void foo() {/* something else*/}  };
template <> class A <3> { void foo() {/* even different*/}  };

以任何方式(比执行速度更快)比

更好
template <int i> class A { 
   void foo() {
      if (i==1) {/* something */}
      else if (i==2) {/* something else*/}
      else if (i==3) {/* even different*/}
   }
};

编辑:

代码是其他人使用的库的一部分。 我正在使用gcc 4.6.3但最终代码将与不同的编译器一起使用。

编辑:

这两段代码使用gcc 4.6.3生成相同的二进制文件。我无法测试完整的情况,因为我的实际代码远远无法使用。这似乎是一个原则问题,反思性,可重用性,可维护性等......

4 个答案:

答案 0 :(得分:6)

速度不是这里的主要问题,但可扩展性是。

专业化的优势在于,您可以让代码的客户更轻松地添加foo()的新重载。假设您稍后决定为i=4添加新行为:在第一种方法中,您只需添加一个新的特化;在第二个版本中,您需要修改函数foo()。如果您以二进制形式发布了库,客户将不会满意。

专业化方法对第二种方法的偏好是开放/封闭原则的表现形式:代码应该是开放的扩展,关闭以进行修改。

答案 1 :(得分:2)

这取决于使用的编译器。我自己编写的代码很多,我的编译器对我做了正确的事情。但是,由于C ++标准中没有任何内容要求编译器在这方面很聪明,所以你也可能遇到麻烦。因此,请确保您的编译器做正确的事情。作为一般经验法则 - 如果您正在编写旨在供其他人使用的可重用库,如果您计划将此代码移植到不同的编译器和/或异国情况的环境等,请不要依赖此功能。

答案 2 :(得分:2)

你问的是“为什么模板专业化会更好”,但请告诉我为什么它更糟糕。我想至少部分i=1i=2i=3的代码是常见的(否则,为什么它具有相同的名称?)。如果是这样,您可能需要在进行专业化时复制一些代码,这会使代码难以维护。

代码重复最好留给编译器,这对于这些if-elseif-else结构非常好。你甚至可以拥有if (i<3),这对于专业化来说是非常尴尬的。

当然,如果你的功能几乎完全不同,那么在使用模板专业化时你就不会遇到这个缺点(并且你会获得优势)。

答案 3 :(得分:2)

有时候将代码编写为一个函数是不可能的,因为对i=1有效的代码可能对i=2无效,即使它永远不会被执行,编译器也会扼杀!

例如:

template <int i> class A { 
   void foo() {
      if (i==1)
      {
          cout << "Easy";
      }
      else if (i==2)
      {
          int stuff[100 * i - 110] = {42}; // error: negative array size for i=1
          cout << stuff[0];
      }
      else if (i==3)
      {
          /* even different*/
      }
   }
};