C++ 为什么这个模板类没有编译?
因此,我有以下代码:C++ 为什么这个模板类没有编译?,c++,templates,constructor,variadic-templates,C++,Templates,Constructor,Variadic Templates,因此,我有以下代码: template <typename Type> class Delegate { public: Delegate(Type x) { } }; void Method() { } int main() { Delegate d(&Method); return 0; } 模板 类委托 { 公众: 委托(x型) { } }; void方法() { } int main() { 代表d(和方法); 返回0;
template <typename Type>
class Delegate
{
public:
Delegate(Type x)
{
}
};
void Method()
{
}
int main()
{
Delegate d(&Method);
return 0;
}
模板
类委托
{
公众:
委托(x型)
{
}
};
void方法()
{
}
int main()
{
代表d(和方法);
返回0;
}
我的问题是:为什么编译器不能根据传入构造函数的内容推断模板类型?我得到的编译错误是:
类模板委托的参数列表丢失。
我理解这一点,但我认为类型推断可以克服这一点,以允许更清晰的语法。因为模板参数推断只适用于函数。类模板总是显式地需要参数
这就是为什么许多模板都有一个“命名构造函数”(namedconstructor)——一个只构造临时实例的函数,但由于它是一个函数模板而不是类模板,所以可以推断参数。比如说
C++11引入了auto
的新含义,它实际上允许您推断变量的类型。因此,如果您有C++11,您可以为您的类创建一个“命名构造函数”,如:
template <typename Type>
Delegate<Type> delegate(Type x) { return Delegate<Type>(x); }
请注意,这会推断出
d
正是初始值设定项返回的类型(如果需要,可以使用auto&
或auto&
,但仅此而已)。这比试图推断假设的委托d(&Method)
要容易得多,因为这将涉及到根据构造函数之间的重载解析推断类型和根据推断类型推断可行构造函数集之间的循环依赖关系(请记住,构造函数可以重载,类型可以部分专用)。这与此不起作用的原因相同:
// attempt to create a std::vector<std::string> of ten "x" strings:
std::vector v(10, "x");
//尝试创建包含十个“x”字符串的std::vector:
标准:向量v(10,“x”);
事实上,它应该会产生完全相同的错误消息
使用类似的方法使用类型推断:
template <class Type>
Delegate<Type> MakeDelegate(Type const &x)
{
return Delegate<Type>(x);
}
模板
委托MakeDelegate(const&x类型)
{
返回代表(x);
}
或者像处理std::vector一样,明确地声明类型
顺便说一下,
main
必须返回int
,以及未知类型的参数(即在模板中)在玩了一段时间后,应该用常量传递&
,这是我想到的,但我不确定。谢谢你的澄清。但是,有什么特别的原因吗?我的意思是,构造函数可以应用类型推断。@WilliamCustde:规则会相当复杂。好消息是在C++11中,您可以使用auto
关键字和相应的命名构造函数来完成。我已经用它扩展了答案。@WilliamCustode:我已经尝试添加了解释为什么Delegate d(&Method)
将比自动
更难。我理解错误,我只是惊讶于构造函数不能使用类型推断,并想知道为什么。谢谢。Jup。错过了最后一句话。已经删除了我的评论:)我感谢关于main和const的帖子注释,但这显然是示例代码。我已经按照你的建议做了,并且制作了一个为你创建对象的方法。谢谢不客气。但是用void main
发布代码有两个很大的缺点:1)它会教那些读错问题的新手。2.)在GCC中,这是一个编译器错误,因此您使人们更难编译示例代码。未知类型的参数通常应通过常量引用传递,但函子类型的参数通常通过值传递@谢谢,这比我的建议更准确。迭代器类型通常也是如此。当然,这在任何情况下都只是一个一般性的指导原则,而不是一个严格的规则。我认为这与所问的问题完全无关。任何阅读C++问题的人都应该理解<代码>主< /代码>是什么。
template <class Type>
Delegate<Type> MakeDelegate(Type const &x)
{
return Delegate<Type>(x);
}