在一个相关问题中,据说没有指向非成员 const 函数的指针。另外,C++11 8.3.5/6 说
函数声明器中 cv-qualifier-seq 的效果与在函数类型之上添加 cv-qualification 不同。在后一种情况下,将忽略 cv 限定符。[ 注意:具有 cv-qualifier-seq 的函数类型不是 cv-qualified 类型;没有 cv 限定的函数类型。——尾注]
如果我理解正确,这意味着不存在非成员 const 函数。(虽然这些函数不是 const 的,但它们不能按照 3.10/6 进行修改)。特别是,指向 const 函数的指针毫无意义。
但是,似乎某些编译器确实在类型推导上下文中创建了指向 const 函数的指针。例如,考虑以下代码:
#include <iostream>
void f() {}
template <typename T> void g( T*) { std::cout << "non const" << std::endl; }
template <typename T> void g(const T*) { std::cout << "const " << std::endl; }
int main() {
g(f);
}
当使用 GCC 和 Intel 编译时,代码输出“non const”,正如我从上面的引用中所期望的那样。但是,使用 Clang 和 Visual Studio 编译时,输出为“const”。
我的解释正确吗?
更新:
在评论之后,我试图澄清我不是在谈论 const 成员函数。我对非成员函数感兴趣(但同样的论点可能也适用于非静态成员函数)。我还更改了问题标题以使其更准确。
与上述解决方案一致g(f)
,以下行对于 GCC 和 Intel 是非法的,但对于 Clang 和 Visual Studio 是不合法的
const auto* ptr = &f;
更新 2:
我同意 Andy Prowl 的解释并选择了他的答案。但是,在那之后,我意识到这个问题是 CWG 的未决问题。