gcc何时编译未使用的模板代码? [英] When does gcc compile unused template code?

查看:191
本文介绍了gcc何时编译未使用的模板代码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码(公认的人为设计),它们在gcc 6中可以很好地编译,但在gcc 7中不能编译。请注意,在 bar 。如果该函数曾经在代码的其他地方引用,则应该打印错误(取消注释 foo.bar()会导致gcc 6打印错误)。但是,即使不使用该功能,gcc 7也会打印错误。



某些更改导致代码也可以与gcc 7一起编译(例如,如果 B A 的定义中被 T 代替),尽管有些更改导致它在gcc 6上失败(例如,如果未使用 this-> )。这里发生了什么? gcc何时决定编译未使用的模板代码?

  struct B {}; 

模板< typename T>
结构体A {

B * bar()
{
//未声明的构造函数
返回新的B(this-> b);
}

B * b;
};

int main(int argc,char * argv [])
{
A< int> foo;

//foo.bar();
}


解决方案

A :: bar()是模板类中的非模板成员函数。如果它本身是模板,则SFINAE将允许在未调用 bar()时编译代码。但是现在您拥有的方式是,一旦使用某些模板参数实例化 A ,则所有这些参数都将是有效的。



一种解决方案是:

  template< typename T> 
结构A {

模板< typename X>
X * bar()
{
// static_assert(is_same< X,B>)如果要
返回新的X(this-&b; b);
}

B * b;
};

然后您将调用 a.bar< B>()而不是 a.bar(),如果不调用它,它将不会被实例化并且不会导致错误。 / p>

I have the following (admittedly contrived) code that compiles just fine in gcc 6, but doesn't compile in gcc 7. Notice the use of an undeclared constructor in the definition of bar. This should print an error if the function is ever referenced elsewhere in the code (uncommenting foo.bar() causes gcc 6 to print an error). However, gcc 7 prints an error even if the function is not used.

Some changes cause the code to also compile with gcc 7 (e.g. if B is replaced with T in the definition of A), while some changes cause it to fail with gcc 6 (e.g. if this-> is not used). What's going on here? When does gcc decide to compile unused template code? Do different versions of gcc use different rules to decide?

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() is a non-template member function in a template class. If it were itself a template, SFINAE would allow the code to compile when bar() is not called. But the way you have it now, once A is instantiated with some template arguments, all of it is expected to be valid.

One solution would be:

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;
};

Then you'd call a.bar<B>() instead of a.bar(), and if you don't call it, it won't be instantiated and won't cause an error.

这篇关于gcc何时编译未使用的模板代码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆