这段代码必须有效吗?

Posted

技术标签:

【中文标题】这段代码必须有效吗?【英文标题】:Must this code works? 【发布时间】:2013-02-11 20:32:55 【问题描述】:

我有下一个使用 gcc 编译的示例代码(4.7.2 使用 -std=c++11):

template<class C>
struct template_test

    C testing() const
    
        return C();
    
;

class A;

struct test : public template_test<A> // (1)
;

struct A
;

int main()

    test t;

在点 (1) 处,函数 template_test&lt;A&gt;::testing() 被实例化,并使用 A 的函数,特别是其默认构造函数。因此,test 包含此实例化函数作为函数成员。但是,此时A 是不完整类型,C++ 禁止使用不完整类型的成员。

这是positive gcc 的错误还是有其他解释?

【问题讨论】:

与您问题的中心点无关,但 clang 给了我一个警告,因为:***.com/questions/4866425/mixing-class-and-struct 【参考方案1】:

template_test::testing() 不仅没有在 (1) 处实例化,它从不 在这个程序中实例化。模板成员仅在使用时实例化,不使用 testing()。为了更清楚地说明这一点,请将代码稍微更改为:

template<class C>
struct template_test

    C testing() const
    
        return C::foo();
    
;

class A;

struct test : public template_test<A> // (1)
;

struct A
;

int main()

    test t;

它也可以正常编译和运行。

【讨论】:

【参考方案2】:

没关系。 testing() 成员函数在您实际调用它之前不会被实例化。要查看这一点,请尝试将其重写如下:

C testing() const

    static_assert(C::value, "Error!");
    return C();

在您尝试调用该函数之前,您会看到不会发出编译错误,但是当您将t.testing() 添加到您的main() 函数时,将触发静态断言。

换句话说,“在点 (1) 处,函数 template_test&lt;A&gt;::testing() 被实例化” 的前提是不正确的。

【讨论】:

当我实例化一个类但我不使用任何成员时,实例化了多少代码? 如果我用false 替换C::value,我总是会得到一个编译错误(甚至评论声明test t;)。如果testing没有实例化,为什么会编译失败? @Peregring-lk:如果您不使用任何成员,则不会实例化任何 code。另外,如果将C::value 替换为false,编译器会检测到您的模板没有可能的有效实例化(条件false 不依赖于任何模板参数),因此它可以在甚至之前直接发出编译错误实例化函数。【参考方案3】:

您正在实例化一个类型不完整的模板,这没关系。

成员函数testing 返回一个不完整类型的实例,这是不行(但是否行得通只有在实例化时才会讨论) .但是,您永远不会调用该函数,因此它永远不会被实例化,因此不会出现错误。单独实例化结构(并调用其构造函数/析构函数)是无害的。

因此,GCC 让您编译它是正确的。当您尝试拨打 testing 时,它会失败。

【讨论】:

它实际上不会失败,因为在实例化点(当您在main() 中调用testing() 时)A 的定义是可见的。

以上是关于这段代码必须有效吗?的主要内容,如果未能解决你的问题,请参考以下文章

错误:必须在 AndroidManifest.xml 中设置有效的 Facebook 应用程序 ID

在 python 2.7 中计算 TF-IDF(三行代码)。这段代码有效吗?

在 .NET 中中止线程时,这段代码会损坏吗?

核心数据中具有自定义类型的所有属性都必须是关系吗?

检查表达式 C# 中的平衡括号

回文字符串问题:为啥我必须放 +1 而不是 -1 才能使这段代码工作?