0

I'm trying to understand the root cause of compile error with following paragraphs.
My objective is that notify consumers per each setting when new setting value was updated.
Following is a simplified version which simulates when setting 1, 2 were updated


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
  });
}

I'm using C++ 17, clang-7, g++8 (devtoolset 8) and CentOS 7

Here are the complains from my compiler (clang-7, g++-8 emits exactly same error message, so I skipped)

[ 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) {
     ^

And it's working fine after add explicit types after ConsumeSettingValue, ConsumeSettingValue<std::string> and ConsumeSettingValue<int32_t>
but I think those lambdas can be deduced as std::function<void(T)> still, without any specific types.

Please shed some light on this. What's wrong with my theory? Thanks in advance.

1 Answers1

0

Found similar case : How to convert a lambda to an std::function using templates

The thing is that template does not consider conversions between types. Therefore std::function and given lambdas can be converted but that does not necessarily can be template deduced.