这段代码必须有效吗?
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<A>::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<A>::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