一般情况下需要模板参数完成的案例是什么?

时间:2015-12-15 16:26:06

标签: c++ templates

考虑简单的代码:

struct x;
template<typename> void func(){}

int main() {
    func<x>();
    return 0;
}

上面的代码不要求类x完整,是否还有其他情况不需要x完成? 。另外一般情况下,需要模板参数完成的情况是什么?

3 个答案:

答案 0 :(得分:4)

如果某些模板实例化导致生成要求类型完整的代码,例如,模板参数必须是完整类型。任何需要模板大小的构造参数,成员访问的使用等等。

在您的情况下,根本不使用模板参数。没有实例化将要求类型完整。我们可以很容易地导致错误:

struct x;

template<typename T> void func()
{ T a; } //requires complete type

int main() {
    func<x>();
}
海湾合作委员会说:

  

错误:&#39; x a&#39;有不完整的类型

如果我们使用指针或引用,则不需要完整的类型:

template<typename T> void func()
{ T* a; } //does not need complete type

请注意,类型需要在实例化时间完成。这意味着只要您在模板中使用和该模板的实例化之间定义结构,您就可以了。这很干净地编译:

struct x;

template<typename T> void func()
{ T a; } //requires complete type

struct x{}; //we now define x

int main() {
    func<x>(); //instantiation
}

请注意,模板类的成员函数仅在使用时实例化。因此,只要您不使用这些成员函数,就可以使用具有成员函数的模板类,该模板类需要具有不完整模板参数的完整类型。

例如,使用以下代码:

struct x;

template <typename T>
struct Foo {
    void bar() {
    }

    void baz() {
        T a;   
    }
};

这是有效的:

Foo<x> a;
a.bar();

但这不是:

Foo<x> a;
a.baz(); //requires complete type

答案 1 :(得分:3)

要求x完成,您需要了解x在内存中的排列方式。例如:

struct x;
template<typename> void func() {
    // Compiler error: what is x::foo ???
    std::cout << x.foo() << std::endl;
}
int main() {
    func<x>();
    return 0;
}

答案 2 :(得分:3)

与其他地方相同:如果

,您可以使用不完整的类型
  • 您只使用指向
  • 类型的指针
  • 或参考
  • 或将其用作声明中的参数

不使用指针/引用来访问成员。