【问题标题】:Another Way to do Templates in C++?在 C++ 中做模板的另一种方法?
【发布时间】:2012-08-14 11:44:50
【问题描述】:

当我发现这种创建模板类的依赖于预处理器的方法时,我只是在搞砸:

#include <iostream>
#include <typeinfo>

// Is this a valid template class?
#define TEMPLATE_CLASS(T)\
class TemplateClass_ ## T\
{\
private:\
    T value;\
public:\
    void print_type()\
    {\
        std::cout << typeid(T).name() << std::endl;\
    }\
}

class Sample {};

TEMPLATE_CLASS(int) obj1;
TEMPLATE_CLASS(char) obj2;
TEMPLATE_CLASS(Sample) obj3;

int main(int argc, char* argv[])
{
    obj1.print_type();
    obj2.print_type();
    obj3.print_type();
}

我简单地编译了这个:

g++ src.cpp -o main.exe

输出:

i
c
6Sample

现在,如您所见,它的工作方式与模板类几乎相同。除了一个明显的事实之外,对象只能全局声明,因为当您使用TEMPLATE_CLASS(T) 时,它实际上内联定义了一个新类,并且不能在函数中定义新类。解决方案可以是:

TEMPLATE_CLASS(float);

int main() { TemplateClass_float obj; }

无论如何,这给了我很多思考。首先,这甚至可以称为有效的泛型类吗?那么,是否可以使用它代替标准模板功能?显然,使用标准模板功能要方便得多,但我的意思是,这也可以吗?最后,C++ 标准在内部定义的模板功能是否与我对预处理器所做的类似?如果不是,这个实现和 C++ 的标准模板特性有什么区别?

【问题讨论】:

  • C 没有类和函数(结构内部)!!!
  • 阅读 14 par of C++ 标准...那么,宏可以遵循所有这些规则吗?
  • 为什么您会使用它而不是标准模板功能?你想达到什么目的?
  • "有什么区别:"论据推演,专业化。

标签: c++ templates template-classes


【解决方案1】:

仅在最简单的情况下,它与模板的作用相同。尝试使用宏执行此操作:

template <class Ty> class C {};
template <class Ty> class C<Ty*> {};
template <class Ty> class C<std::vector<Ty> > {};

【讨论】:

    【解决方案2】:

    你在做的不是templates,而是macros。使用宏而不是模板是一个很好的方法来射击自己。这是来自msdn的示例

    //macro
    #define min(i, j) (((i) < (j)) ? (i) : (j))
    
    //template
    template<class T> T min (T i, T j) { return ((i < j) ? i : j) }
    

    以下是宏的一些问题:

    1. 编译器无法验证宏参数的类型是否兼容。宏在没有任何特殊类型检查的情况下展开。

    2. i 和 j 参数被计算两次。例如,如果任一参数具有后增量变量,则增量执行两次。

    3. 由于宏是由预处理器扩展的,编译器错误消息将引用扩展的宏,而不是宏定义本身。此外,宏将在调试期间以展开形式显示。

    【讨论】:

    • +1 Using macros instead of templates is a good way to shoot yourself in the leg :D
    • 这并不能真正回答问题,因为您的宏不会创建新的类或函数。一个更符合问题的示例是:#define min(T) T min_##T(T x, T y) { return (x&lt;y)?x:y; }。这没有您列出的大部分问题,但还有其他问题。
    • does the template feature defined by the C++ standard internally do something similar to what I'm doing with the pre-processor?这部分我还是很好奇的。
    • @ApprenticeHacker:不。宏只是内联在代码中。每个使用的参数组合生成模板代码
    【解决方案3】:

    预处理器可用于创建宏,如果您使用的是 C,您可能会使用它来完成您所做的事情。 C++ 提供模板作为语言的一部分,因此您可以执行此操作以及更多其他操作。例如,您的宏不会是强类型的,您将错过大量编译时检查,这可能会发现预处理器永远不会发现的错误。

    在几乎所有情况下都使用宏而不是模板并不是可行的方法。您的代码也将难以维护,因此难以遵循。所以,换一种说法,如果你想让你的同事少看你,并且对提到你的名字感到恼火,那就继续使用宏。 :)

    【讨论】:

    • So, put it another way, if you want your colleagues to think less of you and get annoyed at the mention of your name, go right ahead and use macros. +1。 :D
    【解决方案4】:

    嗯,它混淆了类的实际类型,从而使使用函数等变得更加困难。而且您似乎不能在您的方法中使用模板递归,因为每次使用该宏时它都会定义新类。除此之外,您无法使其图灵完备,因为您无法为模板类定义异常情况。 它还缺乏定义基于值的模板类的能力:D 我认为您可以轻松列出更多问题,但这些可能是主要问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 2015-07-11
      • 2012-04-09
      • 1970-01-01
      相关资源
      最近更新 更多