Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法推断模板参数(vector,std::function)_C++_Templates_C++14 - Fatal编程技术网

C++ 无法推断模板参数(vector,std::function)

C++ 无法推断模板参数(vector,std::function),c++,templates,c++14,C++,Templates,C++14,我创建了一个模板函数,我正在尝试自动推断它的模板参数。 MCVE(): 模板 void foo(const std::vector&v,const std::function&f) { } int main() { 向量v; foo(v,[](const int&){});//好的 //foo(v,[](const int&){});//不好 返回0; } 我最初认为无法推导分配器,但这似乎无法解决问题。 我的下一个猜测是它与lambda to std::函数有关,但不知道进一步的步骤。有人知

我创建了一个模板函数,我正在尝试自动推断它的模板参数。 MCVE():

模板
void foo(const std::vector&v,const std::function&f)
{
}
int main()
{
向量v;
foo(v,[](const int&){});//好的
//foo(v,[](const int&){});//不好
返回0;
}
我最初认为无法推导分配器,但这似乎无法解决问题。 我的下一个猜测是它与lambda to std::函数有关,但不知道进一步的步骤。有人知道我该怎么做才能推断吗

PS:我知道“const int”可以变成“int”,但是在实际的代码中,有一个非标量数据类型。

不考虑隐式转换。

类型演绎不考虑隐式转换(除了上面列出的类型调整):这是以后发生的工作。

然后,由于未考虑从lambda到
std::function
的隐式转换,第二个函数参数
f
上模板参数
值的类型推断失败

正如您所展示的,您可以显式地指定模板参数(以绕过模板参数推断)。或者,您可以通过使用将第二个参数声明为,将其从演绎中排除

使用以下命令指定的类型的嵌套名称说明符(范围解析运算符
::
左侧的所有内容):

e、 g

模板
void foo(const std::vector&v,const std::function&f)
{
}


PS:由C++20支持;如果您正在使用的编译器不支持它,那么制作一个也不难。

需要一些时间来理解为什么这样做,但希望能有所帮助。谢谢。那么我是否正确地理解了std::type_identity::type是什么使得第二个值参数位于作用域解析运算符::的左侧,因此是非推断上下文?@turoni Yes。然后,
Value
将仅在第一个函数参数上推导,一切都很好。
std::type_identity
非常简单。我一定写了很多复杂的解决方案,这些解决方案可以通过使用这样的助手来简化。赛尔夫注意:现在,记住这一点。@turoni您在
type_identity
中将
type
定义为
private
;将其
公开
:)您可能会删除
std::function
并使用
template void foo(const std::vector&v,Func&&f){}
请注意
std::vector
可能有两个以上的模板参数,而您的代码没有考虑到这一点。@rubenvb您的意思是什么,查看一下,我只看到带有2个模板参数的实现。@Jarod42这是一个很好的建议,但我也非常喜欢签名显示应该传递给函数/lambda的参数。C++20应该有这样的概念:-)
template<class Value, class Allocator>
void foo(const std::vector<Value, Allocator>& v, const std::function<void(const Value&)>& f)
{
}

int main()
{
    vector<int> v;
    foo<int>(v, [](const int&){}); //okay
    //foo(v, [](const int&){}); //not okay
    return 0;
}
template<class Value, class Allocator>
void foo(const std::vector<Value, Allocator>& v, const std::function<void(const std::type_identity_t<Value>&)>& f)
{
}