派生的模板类型不适用于"std::function"



我正试图通过以下段落了解编译错误的根本原因
我的目标是在更新新的设置值时,根据每个设置通知消费者
以下是一个简化版本,模拟设置1、2更新时的情况


template <typename T>
struct Setting {
T Get() {
return T {};
}
};
template <typename T>
void ConsumeSettingValue(Setting<T>& a, std::function<void(T)> consumer) {
consumer(a.Get());
}
int main() {
Setting<std::string> s1;
Setting<int32_t> s2;
ConsumeSettingValue(s1, [](std::string v){
// Do consume
});
ConsumeSettingValue(s2, [](int32_t v){
// Do consume
});
}

我使用的是C++17、clang-7、g++8(devtoolset 8(和CentOS 7

以下是我的编译器的抱怨(clang-7,g++-8发出完全相同的错误消息,所以我跳过了(

[ 25%] Building CXX object CMakeFiles/UntitledLink.dir/main.cpp.o
/home/kdy/practice/untitled/main.cpp:196:3: error: no matching function for call to 'ConsumeSettingValue'
ConsumeSettingValue(s1, [](std::string v){
^~~~~~~~~~~~~~~~~~~
/home/kdy/practice/untitled/main.cpp:188:6: note: candidate template ignored: could not match 'function<void (type-parameter-0-0)>' against '(lambda at /home/kdy/practice/untitled/main.cpp:196:27)'
void ConsumeSettingValue(Setting<T>& a, std::function<void(T)> consumer) {
^
/home/kdy/practice/untitled/main.cpp:200:3: error: no matching function for call to 'ConsumeSettingValue'
ConsumeSettingValue(s2, [](int32_t v){
^~~~~~~~~~~~~~~~~~~
/home/kdy/practice/untitled/main.cpp:188:6: note: candidate template ignored: could not match 'function<void (type-parameter-0-0)>' against '(lambda at /home/kdy/practice/untitled/main.cpp:200:27)'
void ConsumeSettingValue(Setting<T>& a, std::function<void(T)> consumer) {
^

在ConsumerSettingValue、ConsumeSettingValue<std::string>ConsumeSettingValue<int32_t>
之后添加显式类型后,它运行良好,但我认为这些Lambda仍然可以推断为std::function<void(T)>,没有任何特定类型。

请阐明这一点。我的理论怎么了?提前谢谢。

发现类似的情况:如何使用模板将lambda转换为std::函数

问题是该模板不考虑类型之间的转换。因此,std::function和给定的lambda可以被转换,但不一定可以被模板推导。

最新更新