【问题标题】:How does c++ compiler infer template parameters when only some providedc++编译器在只提供一些时如何推断模板参数
【发布时间】:2015-03-13 06:50:41
【问题描述】:

我有这个类模板:

template<class Q, class V>
bool EQ(const Q& q, V v) { 
    return q.Eq(v); 
}

还有这个类:

struct TEq01 { 
    char n1;                
    TEq01(const void* p) : n1(*(char*)p)     { }    
    bool Eq(char n) const                { return n1 == n; }
};

假设我这样使用它 - 只指定第一个模板参数

char *sz = "some string";
bool f = EQ<TEq01>(sz, '1');

编译器如何知道 TEq01 是 class Q 而不是 class V?我正在使用 Visual Studio 2013。

【问题讨论】:

  • 你就不能想出更好的标识符吗?至少对于这个例子?
  • 哪些标识符?有很多!
  • TEq01,或EQ。常见的元句法名称是foobarfoobar。示例代码还包括许多冗余行,例如像Eq 这样与问题本身无关的定义成员。
  • 好的,我清理一下。我把它从我真正的实时代码中拿出来并修剪了一堆东西,但正如你所指出的那样还不够。一秒……
  • 谢谢,这让问题阅读起来更有趣。

标签: c++ templates c++11 type-inference


【解决方案1】:

这是一个模板函数。函数模板从它们传递的任何内容中获取它们的参数类型。能够在箭头中指定类型是您不需要使用的可选功能,除非您试图强制使用特定类型。

当您在箭头中指定类型时,编译器会按 1、2、3 的顺序执行。您未显式设置的任何类型都从函数参数中获取类型。

【讨论】:

  • 问题是当我只提供 EQ 时,编译器怎么知道我的意思是 EQ 它可以假设我的意思是 EQ 不是吗?跨度>
  • 不,因为EQ 函数先取 Q 再取 V。它推断由于“sz”是 TEq01 类型,它必须是,并且由于第二个 arg 是 char 类型,它一定是这样的。
  • 您是在问编译器是如何做到这一点的(可能过于宽泛),还是语言规范对这种行为有什么看法?
  • 它是位置性的。第一个是第一个,第二个是第二个,依此类推。
  • 好的,有道理。哇,我刚刚做了一个实验。我能够调用 EQ 和 EQ 看起来您可以通过这种方式指定模板参数的任何子集。
【解决方案2】:

我只是想知道编译器如何知道 TEq01 是 Q 类而不是 V 类?我正在使用 Visual Studio 2013。

您提供的第一个模板参数第一个模板参数

模板参数的顺序保持不变。

既然你写了:

template<class Q, class V>
bool EQ...

调用EQ&lt;TEq01&gt; 的意思是“QTEq01 并且没有提供V,所以必须推导出来。”

【讨论】:

  • 您可以添加您可以将参数留空,因此 EQ 是一种提供 V 并保留 Q 推导的方法。
  • @johnnycrash 我很确定这在语法上是错误的。
  • 我的语法可能很差! EQ 已编译!
  • @johnnycrash 哪个编译器?如果它编译它要么是一个错误,要么是一个非标准的扩展。
猜你喜欢
  • 1970-01-01
  • 2020-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-20
  • 1970-01-01
  • 2014-11-20
相关资源
最近更新 更多