【发布时间】:2017-02-14 10:51:59
【问题描述】:
这里我定义了一个类模板 Foo,特化它的成员函数,然后为那个类提供一个部分特化:
// this is Foo_0
template<typename T, typename S>
class Foo {
public:
void operator()() {
std::cout << "Foo_0\n";
}
template<typename R>
void bar(R) {
std::cout << "I'm from Foo_0\n";
}
};
template<>
template<>
void Foo<double, int>::bar(double) {
std::cout << "Now I'm specialized!\n";
}
// this is Foo_1
template<typename T>
class Foo<T, int> {
public:
void operator()() {
std::cout << "Foo_1\n";
}
};
我像这样在 VS2015 上实例化 Foo:
Foo<double, int> f;
f();
令人惊讶的是,f() 打印出“Foo_0”,这意味着未选择部分专用模板 Foo_1。 更奇怪的是,当我评论 Foo::bar(double) 的特化时,f() 会打印“Foo_1”!
然后我测试一下:
Foo<int, int> f;
f();
这一次,f() 也打印“Foo_1”,应用了类特化。
因此,成员 bar() 的特化似乎确实影响了类模板的部分特化的应用。真的吗?为什么会这样?
【问题讨论】:
-
尝试将显式函数模板特化移到部分类模板特化之下。
-
@Kerrek SB 当我移动它时,编译器抱怨“类 Foo 没有成员 Bar”,似乎 bar(double) 被视为 Foo_1 的成员。
-
gcc 成功诊断问题(与 clang 相反)Demo。 (
error: partial specialization of 'class Foo<T, int>' after instantiation of 'class Foo<double, int>' [-fpermissive]) -
bar的显式特化导致Foo<double, int>的隐式实例化,这比Foo<T, int>更好地匹配,因此您得到Foo_0与特化的bar和Foo_1时你把它注释掉。
标签: c++ templates partial-specialization