Search code examples
templatesd

Function return type mismatch phenomenon when returning different input ranges


I get this error: Error: mismatched function return type inference of when I return different type of InputRanges from within the same function. The type returned by take or takeExactly is for some reason compatible with the original input range, but not compatible with my custom input range.

auto decode(Range)(Range r) {
  if (r.front == 0) {        
    r.popFront();
    return r;
  } else if (r.front == 1) {
    r.popFront();
    return r.take(3); // this is compatible with the return type above
  } else if (r.front == 2) {
    r.popFront();
    return MyRange(r); // this is not compatible with the types above
  }
}

What's going on?


Solution

  • The template Take(R) wouldn't change anything to the message error you get from the compiler. The problem is that the return type varies in a function that only works at run-time.

    Different return types could only be inferred at compile time but in this case r.front value wouldn't be known.

    To simplify here is an example that gets rid of the ranges and reproduces the problem

    // t can be tested at compile-time, fun is a template
    auto fun(int t)()
    {
        static if (t == 0) return "can be inferred";
        else return new Object; 
    }
    
    // t cant be tested at compile-time and this produces your error:
    // Error: mismatched function return type inference of typethis and that 
    auto notfun(int t)
    {
        if (t == 0) return "cant be inferred";
        else return new Object; 
    }
    
    void main(string[] args)
    {
        import std.stdio;
        fun!0().writeln; // works, returns a string
        fun!1().writeln; // works, returns an int
    }
    

    Finally what you have two choices:

    • find a common type
    • test r.front out of the function and call different overload according to the value.