是否有将模板用作全局类型而不是参数的方法

Is there anyway to use templates NOT as parameters, but as a global type?

本文关键字:参数 方法 类型 全局 是否      更新时间:2023-10-16

无论何时创建模板,我都知道要将其作为函数参数传递,但我不能在主函数中使用模板有什么特殊原因吗?

template <class Tmp>
int main()
{
   Tmp pizza;
}

但作为参数传递将始终有效

template <class Tmp>
Tmp add(Tmp x, Tmp y)
{
    return x+y;
}

上面的代码不会运行,在我尝试的变量声明行旁边,它表示"未知类型'Tmp'",但我认为,因为我在主函数之外声明了模板,所以它会考虑到这一点。为什么会这样?似乎每个人都只是在函数参数中使用模板,而不是其他什么。

您已接近目标。但是C++是一种静态类型的语言,因此编译器需要在编译时知道pizza类型。这个

template <class Y> struct/*members are public by default*/ Tmp
{
    typedef Y type;
};
int main()
{
    Tmp<int>::type pizza; /*pizza will be an int*/
}

是合法的。

我不能在我的主要功能中使用模板,有什么特别的原因吗

没有理由不能,但您的代码不使用主函数中的模板。相反,您的代码试图将main定义为一个函数模板。这是不好的,因为main的签名是在标准中指定的,并且它不是函数模板。诚然,实现可以指定替代方案,但这对您没有帮助,因为您的实现没有指定任何模板函数替代方案。我的编译器(gcc)给出了一个比你的更直接的错误消息,它说:

error: cannot declare ‘::main’ to be a template

你在写作的时候就好像你相信Tmp被称为模板一样。如果是这样,那么通过回顾你的课本/教程/其他什么来纠正这一点。Tmp不是模板。它是一个模板参数。在您的第二个代码片段中,add是一个函数模板,而Tmp仍然不是模板,它是add的模板参数。

您可以在其参数所在的模板中使用模板参数。例如,以下内容很好:

template <class Tmp>
Tmp add(Tmp x, Tmp y)
{
    Tmp total = x + y;
    return total;
}

你的问题只是,当你尝试这个时,你在main中尝试了它,它不能是一个模板。

模板不是代码。模板是。。。它们是模板。在调用模板函数之前,必须先对其进行实例化。例如

template <class T> T foo(T x) { return T;}

这只是一个模板,即如果您单独编写,编译器将不会为此创建一行代码。只有当你实例化并使用它时,编译器才会做一些事情:

int main() {
    int x = 0;
    int y = foo<int>(x);  // compiler instantiates the template and calls the int instance
}

在第一个代码段中,编译器不知道应该使用什么类型来实例化模板。此外,您不能将main作为模板,因为任何程序的入口点都必须是int main()

PS:

似乎每个人都只是在函数参数中使用模板,而不是其他什么。

使用模板可以做更多的事情。每当可以在编译时选择参数时,我喜欢将模板视为对代码进行参数化的方式。考虑一下这个(有点做作)例子:

// template taking a functor as argument
// (more precisely: a default constructible callable type)
template <typename op,typename T> void plug(T x) {
   std::cout << "op(" << x << ") = " << op()(x) << "n";
}
// a simple functor
template <typename T>
struct identity { T operator()(T x){return x;} };   
int main() {
    plug<identity<double>,double>(2.0);
}
// prints: 
// op(2) = 2

一旦实例化,参数就不会显示为函数参数,而是控制(模板化的)函数对其参数的实际操作。