【问题标题】:Why is this Template Class Not Compiling?为什么这个模板类没有编译?
【发布时间】:2014-03-28 19:23:28
【问题描述】:

所以我有以下代码:

template <typename Type>
class Delegate
{
public:
    Delegate(Type x)
    {
    }
};

void Method()
{
}

int main()
{
    Delegate d(&Method);
    return 0;
}

我的问题是:为什么编译器不能根据传入构造函数的内容推断模板类型?我得到的编译错误是:Argument list for class template Delegate is missing. 我明白这一点,但我认为类型推断可以克服这个问题以允许更清晰的语法。

【问题讨论】:

  • 我理解错误,我只是对构造函数不能使用类型推断感到惊讶并且想知道为什么。谢谢。
  • 朱普。错过了最后一句话。已经删除了我的评论:)

标签: c++ templates constructor variadic-templates


【解决方案1】:

因为模板参数推导只适用于函数。类模板总是显式地需要参数。

这就是为什么许多模板都有一个“命名构造函数”,这个函数只是构造一个临时实例,但由于是一个函数模板而不是类模板来推断参数。例如std::make_pair

C++11 引入了auto 的新含义,它实际上允许您推断变量的类型。所以如果你有 C++11,你可以为你的类创建一个“命名构造函数”,比如:

template <typename Type>
Delegate<Type> delegate(Type x) { return Delegate<Type>(x); }

您可以使用它创建一个推导类型的变量,例如:

auto d = delegate(&Method);

注意,这会推断出d 正是初始化器返回的类型(如果需要,您可以使用auto &amp;auto &amp;&amp;,但仅此而已)。这比尝试推断假设的Delegate d(&amp;Method) 容易得多,因为这将涉及根据构造函数之间的重载决议推断类型和根据推断的类型(请记住,构造函数可以重载并且类型可以部分专业化)。

【讨论】:

  • 玩了一段时间后,这就是我想出的,但我不确定。感谢您的澄清。但是,有什么特别的原因会出现这种情况吗?我的意思是,构造函数可以应用类型推断是有道理的。
  • @WilliamCustode:规则会相当复杂。好消息是,在 C++11 中,您可以使用 auto 关键字和适当的命名构造函数来实现。我已经扩展了答案。
  • @WilliamCustode:我试图解释为什么Delegate d(&amp;Method)auto 更难。
【解决方案2】:

这不起作用的原因相同:

// attempt to create a std::vector<std::string> of ten "x" strings:
std::vector v(10, "x");

事实上,它应该会产生同样的错误信息。

使用类似这样的东西来使用类型推导:

template <class Type>
Delegate<Type> MakeDelegate(Type const &x)
{
    return Delegate<Type>(x);
}

或者像 std::vector 那样做,明确声明类型。

顺便说一句,main 必须返回int,未知类型的参数(即在模板中)应该使用const&amp; 传递。

【讨论】:

  • 我很欣赏关于 main 和 const 的后注,但这显然是示例代码。我已经按照您的建议进行了操作,并制作了一种为您创建对象的方法。谢谢!
  • 不客气。但是使用void main 发布代码有两个很大的缺点:1.) 它会教那些正在阅读您的问题的新手错误的东西。 2.) 在 GCC 中,这是一个编译器错误,所以你让人们更难编译你的示例代码。
  • 未知类型的参数通常应该通过 const 引用传递,但 functor 类型的参数通常按值传递!
  • @JanHudec:谢谢,这实际上比我的建议更准确。迭代器类型通常也是如此。当然,无论如何,这只是一个一般性的指导方针,而不是严格的规定。
  • 我认为这与所提出的问题完全无关。任何阅读 C++ 问题的人都应该了解 main 是什么。
猜你喜欢
  • 1970-01-01
  • 2011-04-07
  • 2010-11-24
  • 2013-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多