gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 17:39:56 25 4
gpt4 key购买 nike

考虑以下程序:

#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++ 给出以下编译器错误(参见现场演示 here)

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++ 时使用了 -pedantic-errors 并且我使用了 /W4 & /Za 使用 VC++ 编译器时的选项。查看现场演示 here & here .所以,我想知道这里如何推导模板类型参数 T ?如果我从程序中删除 const 那么它也可以在 g++ 上正常编译。如果我使用 const T& 那么它在所有 3 个编译器上都能正常编译。那么,在这些情况下,这里将如何推导出类型?

更新:

此程序在英特尔 C++ 编译器上的编译也失败。查看现场演示 here .那么,这是 g++ 和 Intel C++ 中的错误还是 Clang++ 和 VC++ 中的错误?

最佳答案

这本质上是 CWG issue 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.

目前仍然有效。真的不可能说哪个编译器是正确的。尽管如 2015 年的说明所示,CWG 目前的共识是应拒绝该提议。


为了提供更多上下文,我们必须记住带有 cv-qualifier-seq 的函数类型具有特殊含义(想想成员函数),而不仅仅是一种类型,它指定了一些不可修改的东西。此外,您甚至不能以某种偷偷摸摸的方式添加 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. In the latter case, the cv-qualifiers are ignored. [ Note: A function type that has a cv-qualifier-seq is not a cv-qualified type; there are no cv-qualified function types. — end note ][ Example:

typedef void F();
struct S {
const F f; // OK: equivalent to: void f();
};

— end example ]

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

另一方面,如果您使用的是引用而不是指针,则标准中有机制可以推断出它。

所以目前还不清楚应该如何解决这个问题。一方面,今天的措辞本身不允许它,但另一方面,它的机制已经到位以供引用。因此,一些实现会继续对指针执行相同的操作。

关于c++ - 函数指针的模板参数推导(g++ & ICC vs Clang++ & VC++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49295709/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com