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++ ';模板参数推导/替换失败';加上一个论据之后_C++_Templates_C++11_Template Argument Deduction - Fatal编程技术网

C++ ';模板参数推导/替换失败';加上一个论据之后

C++ ';模板参数推导/替换失败';加上一个论据之后,c++,templates,c++11,template-argument-deduction,C++,Templates,C++11,Template Argument Deduction,我需要一个模板函数,它将调用其他函数,参数取自std::tuple。 我编写了一些代码,可以正确编译: #include <tuple> template<typename ...ARGS1, typename ...ARGS2> void foo(const std::tuple<ARGS1...> &, const std::tuple<ARGS2...> &) { //call function } int mai

我需要一个模板函数,它将调用其他函数,参数取自
std::tuple
。 我编写了一些代码,可以正确编译:

#include <tuple>

template<typename ...ARGS1, typename ...ARGS2>
void foo(const std::tuple<ARGS1...> &, const std::tuple<ARGS2...> &)
{
    //call function
}

int main()
{
    std::tuple<int, bool> tuple1(0, false);
    std::tuple<double, void*, float> tuple2(0.0, nullptr, 0.0f);
    foo(tuple1, tuple2);
    return 0;
}
#包括
模板
void foo(常量std::tuple&,常量std::tuple&)
{
//调用函数
}
int main()
{
std::tupletuple1(0,false);
std::tupletuple2(0.0,nullptr,0.0f);
foo(tuple1,tuple2);
返回0;
}
现在我需要再添加一个参数,它是指向函数的指针:

#include <tuple>

template<typename ...ARGS1, typename ...ARGS2>
void foo(const std::tuple<ARGS1...> &, const std::tuple<ARGS2...> &, void (*)(ARGS1..., ARGS2...))
{
    //call function
}

void bar(int, bool, double, void*, float)
{
}

int main()
{
    std::tuple<int, bool> tuple1(0, false);
    std::tuple<double, void*, float> tuple2(0.0, nullptr, 0.0f);
    foo(tuple1, tuple2, &bar);
    return 0;
}
#包括
模板
void foo(常量std::tuple&,常量std::tuple&,void(*)(ARGS1…,ARGS2…)
{
//调用函数
}
空栏(整数、布尔、双精度、空*、浮点数)
{
}
int main()
{
std::tupletuple1(0,false);
std::tupletuple2(0.0,nullptr,0.0f);
foo(tuple1、tuple2和bar);
返回0;
}
我尝试了许多不同的方法,但编译器总是返回
模板参数推断/替换失败
参数包推断与“”和“”
不一致。我不明白,我的代码怎么了。编译器输出中没有任何有用的信息


有人能帮我把这个写好吗?

我的问题有一个很好的答案,它消失了。我不知道为什么

这不是我的想法,但我不记得作者了

template<typename ...ARGS1, typename ...ARGS2, typename ...ARGS3>
void foo(const std::tuple<ARGS1...> &, const std::tuple<ARGS2...> &, void (*)(ARGS3...))
{
    //call function
}
模板
void foo(常量std::tuple&,常量std::tuple&,void(*)(ARGS3…)
{
//调用函数
}

我的问题有一个很好的答案,它消失了。我不知道为什么

这不是我的想法,但我不记得作者了

template<typename ...ARGS1, typename ...ARGS2, typename ...ARGS3>
void foo(const std::tuple<ARGS1...> &, const std::tuple<ARGS2...> &, void (*)(ARGS3...))
{
    //call function
}
模板
void foo(常量std::tuple&,常量std::tuple&,void(*)(ARGS3…)
{
//调用函数
}

由于在本例中,clang++显示了一种不同(而且奇怪)的行为,所以我不能完全确定这个答案。但是,我想我可以解释使用g++时发生了什么

让我们看一下以下示例:

#include <iostream>

template<typename ...ARGS1, typename ...ARGS2>
void foo(void (*)(ARGS1..., ARGS2...))
{
    std::cout << __PRETTY_FUNCTION__ << "\n";
}

void bar(int, bool, double, void*, float) {}

int main() {
    foo(&bar);
}
正如我们所看到的,g++没有为
ARGS1
推导任何东西,而是为
ARGS2
推导了
bar
的所有类型的函数参数


模板参数推导分别适用于每个函数参数。如果模板参数
T
是从两个函数参数推导出来的,则推导出的类型必须相同(只有少数例外)。同样,对于参数包。考虑:

template<typename T>
void foo(T, T) {}

foo(1, 2.3)
第一个和第二个功能参数的
T.
推导结果不一致。这种不一致会导致编译错误


正如我们在回答的第一部分所看到的,对于如下参数:

template<typename ...ARGS1, typename ...ARGS2>
void foo(void (*)(ARGS1..., ARGS2...))
然后,
ARGS2
的扣除结果必须一致:

void bar(int, double);
tuple<int, double> t;
foo(&bar, t); // works

tuple<double> u;
foo(&bar, u) // fails: inconsistent deduction results.
对于像
some\u class\u template::nested\u type
这样的参数,
T
处于非推断上下文中。这在上面的例子中使用,尽管有一些语法上的修饰


通常在C++中传递函数到另一个函数的方式是不同的,虽然:

template<typename F>
void foo(F f)
{
    //call function, e.g.
    f(42);
}
模板
无效foo(F)
{
//调用函数,例如。
f(42);
}

这允许传递任意函数对象,包括指向函数的指针。

因为在这种情况下,clang++表现出不同(而且奇怪)的行为,所以我不能完全确定这个答案。但是,我想我可以解释使用g++时发生了什么

让我们看一下以下示例:

#include <iostream>

template<typename ...ARGS1, typename ...ARGS2>
void foo(void (*)(ARGS1..., ARGS2...))
{
    std::cout << __PRETTY_FUNCTION__ << "\n";
}

void bar(int, bool, double, void*, float) {}

int main() {
    foo(&bar);
}
正如我们所看到的,g++没有为
ARGS1
推导任何东西,而是为
ARGS2
推导了
bar
的所有类型的函数参数


模板参数推导分别适用于每个函数参数。如果模板参数
T
是从两个函数参数推导出来的,则推导出的类型必须相同(只有少数例外)。同样,对于参数包。考虑:

template<typename T>
void foo(T, T) {}

foo(1, 2.3)
第一个和第二个功能参数的
T.
推导结果不一致。这种不一致会导致编译错误


正如我们在回答的第一部分所看到的,对于如下参数:

template<typename ...ARGS1, typename ...ARGS2>
void foo(void (*)(ARGS1..., ARGS2...))
然后,
ARGS2
的扣除结果必须一致:

void bar(int, double);
tuple<int, double> t;
foo(&bar, t); // works

tuple<double> u;
foo(&bar, u) // fails: inconsistent deduction results.
对于像
some\u class\u template::nested\u type
这样的参数,
T
处于非推断上下文中。这在上面的例子中使用,尽管有一些语法上的修饰


通常在C++中传递函数到另一个函数的方式是不同的,虽然:

template<typename F>
void foo(F f)
{
    //call function, e.g.
    f(42);
}
模板
无效foo(F)
{
//调用函数,例如。
f(42);
}

这允许传递任意函数对象,包括指向函数的指针。

为什么不让函数完全通用?这个问题将消失,除了函数指针之外,您还可以使用函子和lambda
template void foo(…,F func){}
编译器试图从函数模板的第一个和第三个参数推断出
ARGS1
,并得到不同的结果。您可以告诉它不要尝试从第三个参数推断参数包,例如,通过
template struct identity\u t{using type=t;};使用非上下文=typename identity\u t::type的模板
,然后是一个类型为
非推断上下文的参数,但这只是一个解决办法。这对我来说很好(铿锵svn trunk)。@Columbo Hmmm.[temp.decreate.type]/5.7说“函数参数包不会出现在参数声明列表的末尾。”是一个非推断上下文,用于从类型推断模板参数。因此,
ARGS1
应该在第三个参数的非推断上下文中,但是
ARGS2
不应该。如果为第三个参数推导了
ARGS2
,则推导结果应该与第二个参数的推导结果不同,因此我们得到的结果不一致,并且推导失败。@Columbo由于模板参数推导对每个函数模板的函数参数都独立工作,因此没有