c++ - 使用命名空间中的模板调用模板模板方法时出现错误的 clang 错误
问题描述
我有一个模板模板方法,当使用不在命名空间中的模板调用它时,它可以正常工作。但是,当使用命名空间中的模板调用它时,我会收到一个 clang 错误。MSVC 和 gcc 编译没有问题,但只有当我将标准设置为 C++17 时。
这是一个最小的例子
#include <vector>
template<template<typename> typename Template>
Template<int> foo() {
return {};
}
template <typename T>
using my_vector = std::vector<T>;
int main()
{
foo<my_vector>(); // compiles
foo<std::vector>(); // does not compile in clang or without C++17
}
没有 C++17 的 gcc 错误是:
<source>:14:5: error: no matching function for call to 'foo'
铿锵声错误是:
<source>:14:22: error: no matching function for call to 'foo<template<class _Tp, class _Alloc> class std::vector>()'
<source>:4:15: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Template'
C ++ 17 中发生了什么变化以允许这样做,它是clang 产生错误的错误吗?
解决方案
向量是
template<class T, class Allocator=std::allocator<T>>
class vector;
注意它需要2个参数。
在c++17template<class>class
中,如果默认第二个参数,则带有2 个参数的模板可以匹配;在c++14中,这是不正确的。
至于c++17中的 clang,如果您实现此功能,他们会在标准中发现一个错误:(通过上述评论中的 @cpplearner)
(10):尽管是缺陷报告的解决方案,但在所有语言版本中默认禁用此功能,并且可以在 Clang 4 及更高版本中使用标志 -frelaxed-template-template-args 显式启用。对标准的更改缺少模板偏序的相应更改,导致合理且先前有效的代码出现歧义错误。预计此问题将很快得到纠正。
在c++14中,这可能有效:
template<template<class...> class Z>
Z<int> foo() {
return {};
}
因为有规则可以class...
匹配任意数量的参数。
推荐阅读
- node.js - 从终端按顺序执行多个 .js 文件
- ruby-on-rails - 如何在 Rails 6 应用程序中包含来自旧版 Gem 的 Javascript 和 CSS?
- firebase - Firebase Cloud Function 部署失败
- javascript - 如何以适当的方式使用 $(.class) ?
- javascript - 使用相对单位的响应式段落
- python - 如何解决以下sql语法错误
- python - 为什么openpyxl不断将“正常”公式更改为数组公式
- google-analytics - 每个 page_url 的 Google 分析视图,而不是每个标题的视图
- vb.net - 有任何字体不会改变文本 len
- mysql - 关键字“order”附近的 SQL 语法不正确