简体   繁体   English

函数指针的模板参数推导(g ++&ICC vs Clang ++&VC ++)

[英]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.

相关问题 `apply`模板在g ++中编译,但不在clang ++和vc ++中编译 - `apply` template compiles in g++ but not in clang++ and vc++ 在C ++,g ++ / clang ++和vc ++中打印函数的地址,谁是对的? - Print an address of function in C++, g++/clang++ vs vc++ , who is right? C ++朋友函数模板重载和SFINAE在clang ++,g ++,vc ++中的不同行为(C ++ 14模式) - C++ friend function template overloading and SFINAE different behaviors in clang++, g++, vc++ (C++14 mode) 带有默认参数的函数不能用 VC++ 编译,但可以用 g++ 和 clang 编译 - Function with default argument doesn't compile with VC++, but does with g++ and clang g ++和clang ++使用指向可变参数模板函数的指针的不同行为 - g++ and clang++ different behaviour with pointer to variadic template functions g ++和clang ++使用自动参数的模板特化的不同行为 - g++ and clang++ different behaviour with template specialization for auto argument g++ “不允许显式模板参数列表”,但使用 clang++ 编译? - "explicit template argument list not allowed" with g++, but compiles with clang++? G ++,clang ++和std :: function - G++, clang++ and std::function VC ++与G ++,cout - VC++ vs. G++, cout 通用VC ++与G ++查询 - Generic VC++ vs g++ query
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM