为什么不能在函数参数类型中使用模板参数包作为其模板参数列表,所以不能明确指定 [英] Why is template parameter pack used in a function argument type as its template argument list not able to be explicit specified

查看:660
本文介绍了为什么不能在函数参数类型中使用模板参数包作为其模板参数列表,所以不能明确指定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

template <typename, typename>
struct AAA{};

template<typename ...Args>
void f(AAA<Args...> *) {}

int main() {
    f<int, int>(nullptr);
}

此代码导致编译错误。使用 g ++ -std = c ++ 1z 进行编译时,错误显示如下:

This code results in a compile error. When compiling using g++ -std=c++1z the error shows as follows:

prog.cc: In function 'int main()':
prog.cc:8:24: error: no matching function for call to 'f<int, int>(std::nullptr_t)'
     f<int, int>(nullptr);
                        ^
prog.cc:5:6: note: candidate: template<class ... Args> void f(AAA<Args ...>*)
 void f(AAA<Args...> *) {}
      ^
prog.cc:5:6: note:   template argument deduction/substitution failed:
prog.cc:8:24: note:   mismatched types 'AAA<Args ...>*' and 'std::nullptr_t'
     f<int, int>(nullptr);

使用 clang ++ -std = c ++ 1z 错误是:

prog.cc:8:5: error: no matching function for call to 'f'
    f<int, int>(nullptr);
    ^~~~~~~~~~~
prog.cc:5:6: note: candidate template ignored: could not match 'AAA<int, int, Args...> *' against 'nullptr_t'
void f(AAA<Args...> *) {}
     ^
1 error generated.

我正在MSYS2 MinGW-w64环境中运行以上代码。我的GCC版本是GCC 7.1.0,我的Clang版本是4.0.0;我在GCC和Clang中都使用的标准库是与我的GCC编译器捆绑在一起的libstdc ++。

I am running those above in a MSYS2 MinGW-w64 environment. My GCC version is GCC 7.1.0 and my Clang version is 4.0.0; the standard library I use both in GCC and in Clang is the libstdc++ bundled with my GCC compiler.

在我看来,对函数模板的调用foo 明确指定了其模板参数,因此应该已经指定了模板参数包和函数参数类型。但是,上面显示的错误诊断似乎表明函数参数的确切类型与 nullptr 参数不匹配,这似乎仅在推断函数参数时才可能出现。发生。所以我的问题是,为什么会发生这种错误?

In my opinion, the call to function template foo has its template parameter explicitly specified thus the template parameter pack and the function argument type should already be specified. However, the error diagnostics shown above seem to suggest that the exact type of function parameter and the nullptr argument does not match, which seems to be a issue only possible when function argument deduction occurs. So my question is, why does such error occur? Is it just a compiler bug, or does the C++ standard have some rules that indicate the original code is just ill-formed?

推荐答案

您可能认为编译器应该将包推导出为 int,int ,但是C ++标准明确要求您观察到的行为。

You may think the compiler should deduce the pack as int ,int, but the C++ standard explicitly requires the behavior you observed.

[temp.arg.explicit / 9]


模板参数推导可以扩展与模板参数包相对应的模板
参数的序列,即使
序列包含明确指定的模板参数。 [示例:

Template argument deduction can extend the sequence of template arguments corresponding to a template parameter pack, even when the sequence contains explicitly specified template arguments. [ Example:

template<class ... Types> void f(Types ... values);
void g() {
  f<int*, float*>(0, 0, 0);     // Types is deduced to the sequence int*, float*, int
}

结束示例]

上面的意思是,即使指定了某些参数,推论也不会结束。参数包必须始终可以通过自变量推导进行扩展。好像给出的显式参数是带有尾随参数包的模板的实例。结合以下内容:

The above means that even though some of the parameters were specified, deduction doesn't end. The parameter pack must always be expandable by argument deduction. It's as if the explicit arguments that were given are an instantiation of a template with a trailing parameter pack. When coupled with the following:

[temp.arg.explicit / 3]


可以从$ b推论或获得的跟踪模板参数$ b默认模板参数可以从显式
模板参数列表中省略。 未扣除
的尾随模板参数包将被推断为模板参数的空序列。

...

Trailing template arguments that can be deduced or obtained from default template-arguments may be omitted from the list of explicit template-arguments. A trailing template parameter pack not otherwise deduced will be deduced to an empty sequence of template arguments. ...

编译器必须将未推导的参数与一个空包匹配。

The compiler must match the un-deduced arguments to an empty pack. But it has nothing to deduce it from.

因此,您尝试将 Args ... 插入 AAA 可能不匹配。因为类型序列是带有尾随列表的两种类型(编译器无法从 nullptr 推导出为空)。而 AAA 只期望两种类型。

As such, your attempt to plug Args... into AAA cannot possibly match. Because the type sequence is two types with a trailing list (that the compiler cannot deduce as empty from nullptr). While AAA expects just two types.

这篇关于为什么不能在函数参数类型中使用模板参数包作为其模板参数列表,所以不能明确指定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆