Search code examples
c++overloadingiostreamtemplate-argument-deduction

Why can't std::endl be passed as a function argument?


#include <iostream>

void f(auto x)
{
    std::cout << x;
}

int main()
{
    f(std::hex);  // okay

    f(std::endl); // error
                  // candidate template ignored: 
                  // couldn't infer template argument 'x:auto'
}

Why can't std::endl be passed as a function argument?


Solution

  • Because std::endl is a function template, and std::hex is not, it's a single non-overloaded function.

    Passing a function that refers to an entire overload set as an argument is done by resolving to a single concrete type.

    Here what happens is that the caller wants to resolve a type by attempting to make the f function resolve it, except the f function wants the caller to resolve to a specific type so it knows what to deduce to. An "unbreakable shield meets sword is hit by a sword that breaks every shield" situation.