[英]template argument deduction for function pointer (g++ & ICC vs Clang++ & VC++ )
Consider following program: 考虑以下计划:
#include <iostream>
template <typename T>
void foo(const T* x) {
x();
}
void bar() { std::cout<<"bar() is called\n"; }
int main() {
foo(bar);
}
It compiles fine on clang++
& VC++
but g++
gives following compiler error (See live demo here ) 它在
clang++
和VC++
上编译很好,但g++
给出了以下编译器错误(请参阅此处的实时演示)
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);
^
I've used -pedantic-errors
when using g++
& clang++
and I've used /W4
& /Za
option when using VC++ compiler. 我在使用
g++
和clang++
时使用了-pedantic-errors
,在使用VC ++编译器时我使用了/W4
& /Za
选项。 See live demo here & here . 在这里和这里观看现场演示。 So, I want to know how template type parameter T will be deduced here ?
那么,我想知道模板类型参数T将如何推导出来? If I remove
const
from the program then it compiles fine on g++
also. 如果我从程序中删除
const
,那么它也可以在g++
上编译。 If I use const T&
then it compiles fine on all 3 compilers. 如果我使用
const T&
然后它在所有3个编译器上编译好。 So, how exactly type will be deduced here in these cases ? 那么,在这些情况下,如何确切地推断出类型?
Update: 更新:
This program fails in compilation on Intel C++ compiler also. 此程序也无法在英特尔C ++编译器上进行编译。 See live demo here .
在这里查看现场演示。 So, is this bug in
g++
& Intel C++ or bug in Clang++
& VC++ ? 那么,这是
g++
和Intel C ++中的错误还是Clang++
和VC ++中的错误?
This is essentially CWG issue 1584 : 这基本上是CWG问题1584 :
It is not clear whether the following is well-formed or not:
目前尚不清楚以下是否形成良好:
void foo(){} template<class T> void deduce(const T*) { } int main() { deduce(foo); }
Implementations vary in their treatment of this example.
实施方案对这个例子的处理方式各不相同。
Which is currently still active. 目前仍处于活跃状态。 It's not really possible to say which compiler is right.
真的不可能说哪个编译器是正确的。 Though as the note from 2015 indicates, the consensus in the CWG is currently that this should be rejected.
虽然从2015年的说明中可以看出,CWG目前的共识是应该拒绝这一点。
To give a little more context, we must remember that a function type with a cv-qualifier-seq has special meaning (think member functions), and is not simply a type the designates something which may not be modified. 为了给出更多的上下文,我们必须记住,具有cv-qualifier-seq的函数类型具有特殊含义(想想成员函数),并且不仅仅是指定可能不被修改的类型的类型。 Moreover, you can't even add the cv qualification in some sneaky manner, as [dcl.fct]/7 illustrates:
此外,您甚至无法以某种偷偷摸摸的方式添加cv资格,因为[dcl.fct] / 7说明:
The effect of a cv-qualifier-seq in a function declarator is not the same as adding cv-qualification on top of the function type.
cv-qualifier-seq在函数声明符中的作用与在函数类型之上添加cv-qualification不同。 In the latter case, the cv-qualifiers are ignored.
在后一种情况下,忽略cv限定符。 [ Note: A function type that has a cv-qualifier-seq is not a cv-qualified type;
[注意:具有cv-qualifier-seq的函数类型不是cv限定类型; there are no cv-qualified function types.
没有cv限定的函数类型。 — end note ][ Example:
- 尾注] [示例:
typedef void F(); struct S { const F f; // OK: equivalent to: void f(); };
— end example ]
- 结束例子]
There is no way in the language to form a const qualified function type. 语言中没有办法形成const限定函数类型。 And yet, the deduction we need is to have
const T
deduced as void()
. 然而,我们需要的推论是将
const T
推导为void()
。 The former is a const qualified type, and it must also be a function type. 前者是 const限定类型,它也必须是函数类型。 But that's a type that cannot exist!
但那是一种不存在的类型! So how can it be deduced?!
那怎么能推断出来?!
On the other hand there is machinery in the standard to deduce it if you were using a reference instead of a pointer. 另一方面,如果您使用引用而不是指针,则标准中有机器可以推导出它。
So it isn't that clear how this should be resolved. 所以不清楚如何解决这个问题。 On the one hand the wording today doesn't allow it per-se, but on the other hand machinery for it is already in place for references.
一方面,今天的措辞本身并不允许,但另一方面,它的机制已经到位以供参考。 So some implementations go ahead and do the same for pointers.
所以一些实现继续进行,并为指针做同样的事情。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.