使用lambdas进行C ++模板参数推导[重复]

时间:2022-02-06 07:19:23

This question already has an answer here:

这个问题在这里已有答案:

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 (!)

但是,如果我明确地施放lambda它工作(!)

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?

为什么模板参数推断失败?以及如何解决它?

2 个解决方案

#1


4  

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

这是一个不可推断的背景。无法推导出模板参数T.

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:

认为T将被推导为int。没有。它不会被推断为int。因为T可能存在多种可能性。例如,可能存在以下特征:

 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).

因此,即使t是int(与100的类型相同),模板参数也可以是double或float(或任何其他类型)。

#2


0  

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.

标准库函数是一种类型,它可以使用调用operator()来保存您可以调用的任何对象,这意味着在其他方面它是函数类型的对象是一个函数对象。

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){});

在函数实例化期间foo([](string str){});编译器无法推断出“函数”函数对象类的T类型。这样我们就明确指定了导致描述函数依赖关系的更简洁方式的类型。 auto func1 = [](string str){}; FOO(func1的);或foo([](string str){});

#1


4  

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

这是一个不可推断的背景。无法推导出模板参数T.

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:

认为T将被推导为int。没有。它不会被推断为int。因为T可能存在多种可能性。例如,可能存在以下特征:

 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).

因此,即使t是int(与100的类型相同),模板参数也可以是double或float(或任何其他类型)。

#2


0  

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.

标准库函数是一种类型,它可以使用调用operator()来保存您可以调用的任何对象,这意味着在其他方面它是函数类型的对象是一个函数对象。

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){});

在函数实例化期间foo([](string str){});编译器无法推断出“函数”函数对象类的T类型。这样我们就明确指定了导致描述函数依赖关系的更简洁方式的类型。 auto func1 = [](string str){}; FOO(func1的);或foo([](string str){});