【发布时间】:2018-03-15 09:30:23
【问题描述】:
考虑以下程序:
#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,在使用VC++ 编译器时我使用了/W4 和/Zaoption。查看现场演示 here 和 here。那么,我想知道模板类型参数 T 将如何推导出来?如果我从程序中删除const,那么它也可以在g++ 上正常编译。如果我使用const T&,那么它在所有 3 个编译器上都可以正常编译。那么,在这些情况下,这里将如何准确推断类型?
更新:
该程序在英特尔 C++ 编译器上的编译也失败。见现场演示here。那么,这是 g++ 和英特尔 C++ 中的错误还是 Clang++ 和 VC++ 中的错误?
【问题讨论】:
-
使用模板传递函数或谓词的通常方式是普通的“值”,例如
template <typename T> void foo(T x) { x(); }参见例如以the standard algorithm library 中的几乎所有功能为例。您能否详细说明您想使用const指针的原因?
标签: c++ constants language-lawyer function-pointers template-argument-deduction