大家晚上好!
我遇到了一个发痒的问题。说我有以下代码:
#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;
} ;
呃。
答案 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
。