我有以下(公认的设计)代码,它在gcc 6中编译得很好,但是不能在gcc 7中编译。请注意在bar
的定义中使用未声明的构造函数。如果函数在代码中的其他地方被引用,则应该打印错误(取消注释foo.bar()
会导致gcc 6打印错误)。但是,即使未使用该功能,gcc 7也会输出错误。
某些更改会导致代码也使用gcc 7进行编译(例如B
中T
替换为A
),而某些更改会导致gcc失败6(例如,如果未使用this->
)。这里发生了什么? gcc什么时候决定编译未使用的模板代码?不同版本的gcc使用不同的规则来决定吗?
struct B {};
template <typename T>
struct A {
B* bar()
{
// undeclared constructor
return new B(this->b);
}
B* b;
};
int main (int argc, char* argv[])
{
A<int> foo;
//foo.bar();
}
答案 0 :(得分:1)
A::bar()
是模板类中的非模板成员函数。如果它本身就是一个模板,SFINAE将允许在未调用bar()
时编译代码。但是你现在拥有它的方式,一旦A
被一些模板参数实例化,所有这些都应该是有效的。
一种解决方案是:
template <typename T>
struct A {
template <typename X>
X* bar()
{
// static_assert(is_same<X, B>) if you want
return new X(this->b);
}
B* b;
};
然后你打电话给a.bar<B>()
而不是a.bar()
,如果你不打电话,它就不会被实例化,也不会导致错误。
答案 1 :(得分:0)
也许我错过了什么,但你似乎试图从B指针构造一个B对象。而且没有默认构造函数可以做到这一点。所以你肯定要:
struct B {
B( B * b ) {
}
};