在 C++ 中做模板的另一种方法?

Posted

技术标签:

【中文标题】在 C++ 中做模板的另一种方法?【英文标题】:Another Way to do Templates in 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++ 标准...那么,宏可以遵循所有这些规则吗? 为什么您会使用它而不是标准模板功能?你想达到什么目的? "有什么区别:"论据推演,专业化。 可能有人偶然发现了cecilsunkure.blogspot.nl/2012/08/generic-programming-in-c.html 【参考方案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) 

以下是宏的一些问题:

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

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

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

【讨论】:

+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 我认为您可以轻松列出更多问题,但这些可能是主要问题。

【讨论】:

以上是关于在 C++ 中做模板的另一种方法?的主要内容,如果未能解决你的问题,请参考以下文章

Riverpod:在 ConsumerWidget 中覆盖 initState 的另一种方法

将成员保存在数据结构中的另一种方法

Java模版方法的另一种实现

jar包引入interlij的另一种方法

百分位数的另一种方法?

在 ES6 类中实现数据隐私的另一种方法 [重复]