首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数指针的模板参数推导(g++和ICC对Clang++和VC++ )

函数指针的模板参数推导(g++和ICC对Clang++和VC++ )
EN

Stack Overflow用户
提问于 2018-03-15 09:30:23
回答 1查看 219关注 0票数 7

考虑下列方案:

代码语言:javascript
复制
#include <iostream>
template <typename T>
void foo(const T* x) {
    x();
}
void bar() { std::cout<<"bar() is called\n"; }
int main() {
    foo(bar);
}

它在clang++ & VC++上编译得很好,但是g++给出了以下编译器错误(参见live 这里 )

代码语言:javascript
复制
main.cpp: In function 'int main()':
main.cpp:10:9: error: no matching function for call to 'foo(void (&)())'
  foo(bar);
         ^
main.cpp:3:6: note: candidate: template<class T> void foo(const T*)
 void foo(const T* x) {
      ^~~
main.cpp:3:6: note:   template argument deduction/substitution failed:
main.cpp:10:9: note:   types 'const T' and 'void()' have incompatible cv-qualifiers
  foo(bar);
         ^

我在使用g++ & clang++时使用了g++,在使用VC++编译器时使用了/W4 &/Za选项。参见现场演示这里 & 这里。那么,我想知道模板类型参数T是如何推导出来的呢?如果我从程序中删除const,那么它在g++上也会编译得很好。如果我使用const T&,那么它在所有三个编译器上都编译得很好。那么,在这些情况下,如何精确地推导出类型呢?

更新:

此程序在Intel C++编译器上也无法编译。参见现场演示这里。那么,这是g++ & Intel C++中的bug,还是Clang++ & VC++中的bug?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-15 10:34:20

这本质上是CWG第1584期

尚不清楚以下内容是否格式良好: void (){}模板void (const*){} int main() { deduce(foo);} 在此示例中,实现的处理各不相同。

目前仍处于活动状态。要说哪个编译器是正确的是不可能的。虽然正如2015年的说明所示,工作组目前的共识是,应拒绝这一点。

为了提供更多的上下文,我们必须记住,带有cv-限定符-seq的函数类型具有特殊的意义(考虑成员函数),而不仅仅是一种类型,它指定了一些不能修改的内容。此外,您甚至不能以某种鬼鬼祟祟的方式添加cv限定,正如[dcl.fct]/7所说明的:

cv-限定符-seq在函数声明器中的作用与在函数类型的顶部添加cv限定不一样。在后一种情况下,cv-限定符将被忽略。 注释:具有cv-限定符-seq的函数类型不是cv限定类型;没有cv限定函数类型。- end注意事项 

在该语言中无法形成const限定函数类型。然而,我们需要的推论是将const T推导为void()。前者是const限定类型,也必须是函数类型。但那是一种不存在的类型!那么怎么推断呢?!

另一方面,如果您使用的是引用而不是指针,那么标准中就有推断它的机器。

所以现在还不清楚该如何解决这一问题。一方面,今天的措辞不允许它本身,但另一方面,它的机器已经到位,以供参考。因此,有些实现会对指针执行同样的操作。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49295709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档