什么时候gcc编译未使用的模板代码?

时间:2018-02-25 03:00:00

标签: c++ templates gcc copy-constructor

我有以下(公认的设计)代码,它在gcc 6中编译得很好,但是不能在gcc 7中编译。请注意在bar的定义中使用未声明的构造函数。如果函数在代码中的其他地方被引用,则应该打印错误(取消注释foo.bar()会导致gcc 6打印错误)。但是,即使未使用该功能,gcc 7也会输出错误。

某些更改会导致代码也使用gcc 7进行编译(例如BT替换为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();
}

2 个答案:

答案 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 ) {
    }
};