gcc 什么时候编译未使用的模板代码?
When does gcc compile unused template code?
我有以下(诚然是人为的)代码,在 gcc 6 中编译得很好,但在 gcc 7 中无法编译。请注意在bar
的定义中使用未声明的构造函数。如果该函数在代码中的其他地方被引用,这应该会打印错误(取消注释foo.bar()
会导致 gcc 6 打印错误)。但是,即使未使用该函数,gcc 7 也会打印错误。
一些更改导致代码也使用 gcc 7 编译(例如,如果在A
的定义中将B
替换为T
),而一些更改会导致代码在 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();
}
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()
,如果你不调用它,它不会被实例化,也不会导致错误。
也许我错过了一些东西,但您似乎正在尝试从 B 指针构造 B 对象。并且没有默认构造函数可以做到这一点。所以你肯定想要:
struct B {
B( B * b ) {
}
};
相关文章:
- 什么时候调用组成单元对象的析构函数
- 什么时候在C++中返回常量引用是个好主意
- 什么时候调用析构函数
- boost odeint什么时候真正调用观测者
- 编译器对数组声明大小的计算。什么时候发生?
- 什么时候最好在子进程中使用 CPU 或 I/O 密集型代码 [ C++ ]
- 您应该在什么时候创建自己的异常类型
- 我什么时候会默认(而不是删除)基类中的复制和移动操作
- 什么时候可以使用常量装饰调用我的重载函数?
- unordered_map什么时候返回 -1?
- QCoreApplication什么时候有效?
- sizeof(size_t) 和 sizeof(ptrdiff_t) 什么时候会有所不同?
- 什么时候用指针调用C++类构造函数
- 为什么我的代码说"Yes"什么时候应该说"No"?
- gcc 什么时候编译未使用的模板代码?
- 在编译过程中,琐碎的(没有效果的)代码什么时候会被删除
- 我们什么时候应该封装代码才能成为"Class"?
- 宏什么时候能让代码比函数更漂亮
- 我们什么时候在使用Connector/c++的代码中释放对象?
- 当我不输出变量时,代码中断;我什么时候工作。