문제

I have the following template declaration

template<typename T>
void foo(function<void(T)> f){
    // ...
};

But when i call it like this

foo([](string s){ });
// visual studio 13 error message => 
// Error:  void foo(std::function<void(_Type)>)' : 
//could not deduce template argument for 'std::function<void(_Type)>' 
//from 'main::<lambda_58b8897709e10f89bb5d042645824f66>

Template argument deduction fails . Why? how to fix it?

I have the same problem with variadic templates

template<typename ... Tn>
void foo(function<void(Tn ...)> f){
    // ...
};

int main() {
    foo<string,bool>([](string s,bool b){ }); // Works
    foo([](string s,bool b){ }); // Fails
}

But if i explicitly cast the lambda it works (!)

foo((function<void(string,bool)>) [](string s,bool b){ }); // Works

// Or even a simpler syntax with a macro
#define lmda_(a) (function<void a>)[&] a
foo( lmda_((string s, bool b)) { }); // Works (note the extra () )

Why template argument deduction fails ? and how to fix it?

도움이 되었습니까?

해결책

That is a non-deducible context. The template parameter T cannot be deduced.

Here is a simplest example. Given:

 template<typename T>
 struct X
 {
     X(T t) : data(t) {}
     T data;
 };

 template<typename T>
 void f(X<T> param);

Now you're doing something like this:

 f(100);

thinking that T will be deduced to int. NO. It will not be deduced to int. Because there could be more than one possibility for T. For example, there might be specializations as:

 template<>
 struct X<double>
 {
     X(int t) : data(t) {}
     int data;
 };

 template<>
 struct X<float> //another specialization
 {
     X(int t) : data(t) {}
     int data;
 };

So even though t is int (same as the type of 100), the template argument could be double or float (or any other type).

다른 팁

The standard-library function is a type that can hold any object you can invoke using the call operator () which means in other ways that it is an object of type function is a function object.

During function instantiation foo([] (string str){}); There is no way the compiler would deduce the type of T for the "function" function object class This way we explicitly specify the type which leads to neater way of describing the dependencies for the function. auto func1 =[](string str){}; foo(func1); or foo([] (string str){});

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top