【发布时间】:2020-01-27 20:41:37
【问题描述】:
考虑以下代码:
template <typename>
struct S { };
void g(S<int> t);
template <typename T>
void f(T, std::function<void(S<T>)>);
尝试调用时
f(0, g);
我收到以下错误:
error: no matching function for call to 'f' f(0, g); ^ note: candidate template ignored: could not match 'function<void (S<type-parameter-0-0>)>' against 'void (*)(S<int>)' void f(T, std::function<void(S<T>)>); ^
虽然我了解std::function 参数的类型通常无法推断,因为它是非推断上下文
在这种情况下T可以先由传入的参数0推导出来,然后代入std::function<void(S<T>)>得到std::function<void(S<int>)>。
我希望在推断出T=int 之后,编译器会在签名中的所有位置替换T,然后尝试使用参数g 构造std::function 参数。
为什么不是这样?我认为替换/扣除发生的顺序与此有关,但我想看看相关的标准措辞。
额外问题:这是否可以在未来的标准中进行更改,同时保持向后兼容性,或者这种替换不起作用的根本原因是什么?
【问题讨论】:
-
这里没有
std::function或函数指针,为了简化一点:gcc.godbolt.org/z/SHXtwh -
你仍然可以使用
template <typename T> void f(T, std::identity_type_t<std::function<void(S<T>)>>)。 -
@Jarod42
std::identity_type_t标准化了吗? -
@MaxLanghof en.cppreference.com/w/cpp/types/type_identity
标签: c++ c++11 templates language-lawyer template-argument-deduction