- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
对于下面的代码,我在 gcc 中得到了一个模棱两可的模板实例化错误。
但是,使用 Clang 或 Visual Studio 代码编译得很好。
可以在此处找到代码的完整工作示例:
http://coliru.stacked-crooked.com/a/60ef9d73ce95e6f9
我有一个从聚合类型构建的类模板
template<template<typename...> typename AggregateType, typename ...>
struct MyClass;
template<typename ... Bases>
struct Aggregate : Bases...
{ };
// specialization for two argument list for the
// aggregate type
template<template<typename...> typename AggregateType,
typename Base,
typename ... Bases1,
typename ... Bases2>
struct MyClass<
AggregateType,
AggregateType<Bases1...>,
AggregateType<Base, Bases2...>>
{
void func()
{
std::cout << "not specialized\n";
}
};
// specialization for the second argument list with length 1
template<template<typename...> typename AggregateType,
typename Base,
typename ... Bases1>
struct MyClass<
AggregateType,
AggregateType<Bases1...>,
AggregateType<Base>>
{
void func()
{
std::cout << "specialized\n";
}
};
class Foo {};
class Bar {};
int main()
{
// this should give the not specialized class
using NotSpecialized = MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo, Bar>>;
NotSpecialized ns;
ns.func();
// this should give the specialized class
using Specialized = MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo>>;
Specialized s;
s.func();
}
最佳答案
(以下所有 ISO 标准引用均引用 N4659: March 2017 post-Kona working draft/C++17 DIS ,并且所有示例程序结果在 C++11、C++14 和 C++17 的 GCC 和 Clang 上一致)
我相信 GCC 在这里是错误的,但我一直无法找到相应的(开放的)GCC 错误报告。
[temp.class.order]/1涵盖了类模板特化的偏序 [ 重点 矿]:
For two class template partial specializations, the first is more specialized than the second if, given the following rewrite to two function templates, the first function template is more specialized than the second according to the ordering rules for function templates:
- (1.1) Each of the two function templates has the same template parameters as the corresponding partial specialization.
- (1.2) Each function template has a single function parameter whose type is a class template specialization where the template arguments are the corresponding template parameters from the function template for each template argument in the template-argument-list of the simple-template-id of the partial specialization.
// G)
template<template<typename...> typename AggregateType,
typename Base,
typename... Bases1,
typename... Bases2>
void f(MyClass<AggregateType,
AggregateType<Bases1...>,
AggregateType<Base, Bases2...>>);
// F)
template<template<typename...> typename AggregateType,
typename Base,
typename... Bases1>
void f(MyClass<AggregateType, AggregateType<Bases1...>, AggregateType<Base>>);
f
的 G 和 F 重载的偏序受
[temp.func.order]/2 管辖,
[temp.func.order]/3和
[temp.func.order]/4 [
重点 矿]:
[temp.func.order]/2
Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type. The deduction process determines whether one of the templates is more specialized than the other. If so, the more specialized template is the one chosen by the partial ordering process.
[temp.func.order]/3
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template. [...]
[temp.func.order]/4
Using the transformed function template's function type, perform type deduction against the other template as described in [temp.deduct.partial]. [...]
f
生成转换后的模板上面的重载,特别是考虑模板模板参数
AggregateType
(在两个重载中都使用)以及这些重载的实例化与特定的类模板
Aggregate
和类(class)
Foo
和
Bar
,
template<typename ... Bases>
struct Aggregate : Bases...
{ };
class Foo {};
class Bar {};
// G-transformed (argument template>
template<typename... Bases2>
void f(MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo, Bases2...>>);
// F-transformed (argument template>
void f(MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo>>);
[temp.deduct.partial]/2
Two sets of types are used to determine the partial ordering. For each of the templates involved there is the original function type and the transformed function type. [...] The deduction process uses the transformed type as the argument template and the original type of the other template as the parameter template.
[temp.deduct.partial]/10
Function template F is at least as specialized as function template G if, for each pair of types used to determine the ordering, the type from F is at least as specialized as the type from G. F is more specialized than G if F is at least as specialized as G and G is not at least as specialized as F.
[temp.deduct.partial]/11
If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and if G has a trailing parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing parameter pack, then F is more specialized than G.
Bases2
,F 比 G 更专业。存在于 G 但不存在于 F (/11) 中。甚至可以直接应用 [temp.deduct.partial]/10 的第二部分来论证 F 是
更多 专业比G为
Aggregate<Foo>
比
Aggregate<Foo, Bases2...>>
更专业.
Specialized
别名
using Specialized = MyClass<Aggregate, Aggregate<Foo, Bar>, Aggregate<Foo>>;
MyClass
的“第二特化”(来自 OP 帖子) ,特别是重写到上面 F 函数模板的特化,因为这个类模板特化比“第一个特化”(带有附加
Bases2
可变参数模板参数包的那个)更特化。
关于c++ - gcc的模棱两可的模板实例化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62384512/
我从一所大学获得了一些示例代码,导入了项目并尝试运行测试:方法 assertThat(Integer, Matcher) 对于 MyClass 类型是不明确的 每个 assertThat 都被标记为红
关于将 iOS 应用程序迁移到 Swift 3.0 的过程。这是我面临的一个问题。 先上相关代码: let calendar = NSCalendar.current, calendCompo = c
我刚开始研究 Java 8 Lambda 功能。我在 Java 7 中编写了这段代码,并尝试在 lamdas 中执行它。请注意,最后一行会产生编译错误,因为重载的函数不明确。我明白原因。如何使用 la
如何优先(告诉编译器)使用“函数接收引用”(#B)而不是“函数接收值”(#A)? #include using namespace std; class Heavy{/* ...... */}; /
我正在使用 Google Map API V3 显示车辆行驶路径及其路线方向。但是通过谷歌方向图标,很难找到方向。下图解释更多 我看到了每个图标,它是 source 我找到了图片路径,是 http:/
我是一名优秀的程序员,十分优秀!