std::function und operator()



  • Hallo,

    warum funktioniert das nicht, sondern nur über den Umweg beim auskommentieren Teil?

    #include <iostream>
    #include <functional>
    
    template<typename T>
    class Caller
    {
    public:
    	Caller(std::function<void(T)> fn_)
    		: fn(fn_)
    	{
    
    	}
    
    	void doIt(T &&val)
    	{
    		fn(val);
    	}
    
    private:
    	std::function<void(T)> fn;
    };
    
    void foo(int val)
    {
    	std::cout << val;
    }
    
    struct Foo
    {
    	void operator()(int val)
    	{
    		std::cout << val;
    	}
    };
    
    int main()
    {
    	Caller<int> c(foo);
    	c.doIt(1);
    
    	Caller<int> c2(Foo());
    	//Foo f;
    	//Caller<int> c2(f);
    	c2.doIt(1);
    
    	return 0;
    }
    

    Als Fehler gibt der Compiler

    error: request for member 'doIt' in 'c2', which is of non-class type 'Caller<int>(Foo (*)())'

    aus. Er scheint das also als Funktionsdefinition aufzufassen...? Kriegt man das auch als Einzeiler hin?



  • Das ist der tolle most vexing parse. Als Einzeiler geht es so:

    Caller<int> c2((Foo()));  // Doppelte Klammern
    Caller<int> c2{Foo()};  // Uniform Intialization (seit C++11)
    


  • Ah, verstehe, danke dir. 🙂
    Die doppelten Klammern sehen strange aus, dann lieber die geschweiften.


  • Mod

    Ich bevorzuge geschweifte Klammern in Initializern von Temporaries zu verwenden:

    Caller<int> c2(Foo{});
    

    So haben sie nämlich nebenbei einen syntaktischen Aussagewert: Foo ist keine Funktion sondern ein Typ.

    PS: Caller 's Konstruktor sollte wohl explicit sein.


Anmelden zum Antworten