Search code examples
c++c++11lambdac++17auto

auto deduction fails with message "inconsistent deduction for auto return type"


I have written the following test :

#include <cassert>
#include <iostream>
#include <string>
#include <cmath>
#include <functional>

// Works with std::function !
//std::function<double(double)> set_unary_operation(const std::string& unary)
auto set_unary_operation(const std::string& unary)
{
    if(unary == "EXP")
      return [](const double& x){ return std::exp(x);};
    if(unary == "LOG")
      return [](const double& x){ return std::log10(x);};
    if(unary == "_LN")
      return [](const double& x){ return std::log(x);};
    if(unary == "ABS")
      return [](const double& x){ return std::abs(x);};

    return [](const double& x){return x;};

}
  
bool is_equal(double&& value, double&& test)
{
    double epsilon = 0.0000001;
    return (value-epsilon < test) && (value+epsilon > test);
}

int main()
{
  // TEST OPERATOR --------------------------------------------------------------------------
  {
    std::string in = "EXP";

    auto f = set_unary_operation(in);

    std::cout << "f = EXP ; f(1) = "<< f(1) << "; f(2.5) = " << f(2.5) << std::endl;

    assert(is_equal(f(1)  , 2.71828182));
    assert(is_equal(f(2.5), 12.1824939607));
  }

  return 0;
}

The code works fine if I define the return type of set_unary_operation as std::function<double(double)>, but failed when I use auto with the following message :

error: inconsistent deduction for auto return type: ‘moteur_de_calcul::set_unary_operation(const string&)::<lambda(const double&)>’ and then ‘moteur_de_calcul::set_unary_operation(const string&)::<lambda(const double&)>’

I try to understand why the deduction failed (example can be found here : https://onlinegdb.com/Sk7bitBxD).


Solution

  • Every lambda expression yields unique closure type,

    The lambda expression is a prvalue expression of unique unnamed non-union non-aggregate class type, known as closure type, which is declared (for the purposes of ADL) in the smallest block scope, class scope, or namespace scope that contains the lambda expression.

    which causes return type deduction fails because they are not same types.

    If there are multiple return statements, they must all deduce to the same type

    As you said you could specify std::function as the return type instead.