我有下一个使用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的错误还是有其他解释?
答案 0 :(得分:4)
不仅在(1)中实例化template_test :: testing(),而且在此程序中从未实例化。模板成员仅在使用时实例化,并且不使用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;
}
也编译并运行良好。
答案 1 :(得分:2)
没关系。在您实际调用它之前,testing()
成员函数不会被实例化。要查看此内容,请尝试按如下方式重写:
C testing() const
{
static_assert(C::value, "Error!");
return C();
}
在尝试调用函数之前,您将看到没有发出编译错误,但是当您向t.testing()
函数添加main()
时,将触发静态断言。
换句话说,你的前提是“在点(1)函数template_test<A>::testing()
被实例化”是不正确的。
答案 2 :(得分:1)
您正在实例化一个类型不完整的模板,这没关系。
成员函数testing
返回一个不完整类型的实例,不正常(但这是否正常只会在讨论时进行讨论实例化)。但是,您永远不会调用该函数,因此它永远不会被实例化,因此没有错误。单独实例化结构(并调用其构造函数/析构函数)是无害的。
因此,GCC让你编译它是正确的。尝试拨打testing
时,它会失败。