模板类成员VS嵌套类前向声明

时间:2014-05-30 21:22:02

标签: c++ templates c++11

大家晚上好!

我遇到了一个发痒的问题。说我有以下代码:

#include <iostream>

template <class T>
struct MyTemplate {
    int _array[sizeof (T)];
} ;

struct MyStruct {

    struct MyNestedStruct {
        int foo;
    } ;

    MyTemplate<MyNestedStruct> _nested;
} ;

int main(int, char **) {
    return 0;
}

此示例代码段编译正常。我想要做的是将MyNestedStruct的定义从MyStruct中解除:

#include <iostream>

template <class T>
struct MyTemplate {
    int _array[sizeof (T)];
} ;

struct MyStruct {
    struct MyNestedStruct;

    MyTemplate<MyNestedStruct> _nested;
} ;

struct MyStruct::MyNestedStruct {
    int foo;
} ;

int main(int, char **) {
    return 0;
}

当然这个没有编译,因为我要求部分声明类型的大小(错误:'sizeof'无效应用于不完整类型'MyStruct :: MyNestedStruct')。

我的真实用例确实需要sizeof,但也会以这种方式使用几个 MyNestedClass类模板参数,每个参数都完全用构造函数等声明。出于这个原因,我不希望MyClass变得臃肿。我可以对此做些什么,或者我是否必须使用外部作用域(命名空间)来放入我的“内部”类?

除非......

struct MyStruct {
#include "MyNestedStruct.h" // Dirty preprocessor to the rescue !
    MyTemplate<MyNestedStruct> _nested;
} ;

呃。

1 个答案:

答案 0 :(得分:2)

基本上我们需要推迟MyTemplate的模板实例化,因为那是需要T完成的模板实例化。我可以在这里看到的诀窍是模仿MyStruct

 template <typename T>
 struct MyTemplate {
   int _array[sizeof(T)];
 };

 template <typename Dummy = void>
 struct MyStruct {
   struct MyNestedStruct;

   MyTemplate<MyNestedStruct> _nested;
 };

 template <typename Dummy>
 struct MyStruct<Dummy>::MyNestedStruct {
   int foo;
 };

 int main() {}

现在我们推迟了MyStruct的实例化,但我们需要使用MyStruct<>。如果这不令人满意,那么只需提供一个类型别名。

 #include <iostream>

 template <typename T>
 struct MyTemplate {
   int _array[sizeof(T)];
 };

 template <typename Dummy = void>
 struct MyStructImpl {
   struct MyNestedStruct;

   MyTemplate<MyNestedStruct> _nested;
 };

 template <typename Dummy>
 struct MyStructImpl<Dummy>::MyNestedStruct {
   int foo;
 };

 using MyStruct = MyStructImpl<>;

 int main() {
   MyStruct s;
   std::cout << sizeof(s._nested._array) << std::endl;
 }

打印16

注意:您还可以在MyStructImpl命名空间或类似内容中隐藏detail