Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 另一种在C++;?_C++_Templates_Template Classes - Fatal编程技术网

C++ 另一种在C++;?

C++ 另一种在C++;?,c++,templates,template-classes,C++,Templates,Template Classes,当我发现这种依赖于预处理器的创建模板类的方法时,我只是在胡闹: #include <iostream> #include <typeinfo> // Is this a valid template class? #define TEMPLATE_CLASS(T)\ class TemplateClass_ ## T\ {\ private:\ T value;\ public:\ void print_type()\ {\ st

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

#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();
}
输出:

i
c
6Sample
现在,正如您所看到的,它的工作方式与模板类基本相同。除了一个明显的事实之外,对象只能全局声明,因为当您使用
TEMPLATE\u class(T)
时,它实际上会内联定义一个新类,并且不能在函数中定义新类。解决方法可以是:

TEMPLATE_CLASS(float);

int main() { TemplateClass_float obj; }

不管怎么说,这让我想了很多。首先,这甚至可以称为有效的泛型类吗?那么,它是否可以替代标准模板功能?显然,使用标准模板功能要方便得多,但我想说的是,这也可以吗?最后,C++标准定义的模板特征是否与我在预处理器上做的类似?如果不是,那么此实现与C++的标准模板功能有什么区别?

您所做的不是
模板,而是
宏。使用宏而不是模板是一个很好的方法来射击自己的腿。以下是
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)((i)<(j))?(i):(j))
//模板
模板tmin(ti,tj){return((i
以下是宏的一些问题:

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

  • 对i和j参数进行两次评估。例如,如果任一参数具有后增量变量,则增量将执行两次

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


  • 嗯,它混淆了类的实际类型,从而使处理函数等变得更加困难。而且,似乎不能在方法中使用模板递归,因为每次使用宏时它都定义新类。在这一点上,您不能使其图灵完整,因为您不能为模板类定义异常情况。
    它还缺乏定义基于值的模板类的能力:D我认为您可以很容易地列出更多问题,但这些可能是主要问题。

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

    template <class Ty> class C {};
    template <class Ty> class C<Ty*> {};
    template <class Ty> class C<std::vector<Ty> > {};
    
    模板类C{};
    模板类C{};
    模板类C{};
    
    预处理器可用于创建宏,如果您使用的是C语言,您可以使用它来完成您所做的事情。C++提供了模板作为语言的一部分,这样你就可以做更多的事情。例如,您的宏将不是强类型的,您将错过许多编译时检查,这些检查可能会发现预处理器永远不会发现的错误


    在几乎所有情况下都使用宏而不是模板并不是一条可行之路。您的代码也很难维护,因此很难遵循。因此,换一种说法,如果你想让你的同事少想你一点,并对提到你的名字感到恼火,那就直接使用宏吧。:)

    C没有类和函数(在结构内部)!!!读取14标准的C++标准…那么,宏可以遵循所有这些规则吗?为什么要使用它而不是标准模板功能?你想实现什么?”区别是什么:“参数推导、专门化。有人无意中发现使用宏而不是模板的
    可能+1,这是一个打击自己的好方法。
    :这并不能真正回答问题,因为你的宏没有创建新的类或函数。一个更符合这个问题的例子是:
    #define min(T)T min##T(tx,T y){return(X<代码>是否由C++标准定义的模板特征在内部做了类似于我正在处理的预处理器?< /代码>我仍然对这一部分感到好奇。@ Apple TythEnter:没有宏只在代码中加进去。模板代码是针对每一个使用的参数组合生成的。大家如果想少想你一点,一提到你的名字就生气,那就直接用宏吧。
    +1.:D
    template <class Ty> class C {};
    template <class Ty> class C<Ty*> {};
    template <class Ty> class C<std::vector<Ty> > {};