请考虑以下示例:
class MyWrapper {
public:
MyWrapper() {};
private:
ThirdPartyLibraryType impl;
};
假设ThirdPartyLibraryType
没有默认的构造函数,我无法帮助它,因为它是第三方库类型。然后,这段代码将不会编译,因为默认构造函数MyWrapper()
必须调用ThirdPartyLibraryType
的默认构造函数。现在,我只希望默认构造函数什么也不做,因为我使用默认构造函数的用例如下:
std::array<MyWrapper,10> myArray;
for (int i=0;i<10;++i) {
myArray[i] = generateMyWrapper(...);
}
是否有强制生成默认构造函数的方法?(没有开销,我不想使用ThirdPartyLibraryType*
有数据成员的明显解决方案)
编辑:到目前为止,我使用的方法类似于Yakk提出的方法,它不依赖默认的构造函数,但我认为成员函数调用的情况很难看:
template<class T, size_t N, class C, class CF>
std::array<T,N> gen_array(C const& obj, CF&& f) {
...
use obj.f
...
}
class MyClass {
MyWrapper generateMyWrapper(int i) const { ... }
auto genMyWrapperTypeArray() const {
return
gen_array<
MyWrapper,10,MyClass,
MyWrapper(MyClass::*)(int) const
> (
*this, &MyClass::generateMyWrapper
);
}
}
我还没有对它进行测试,我的要点是,如果语法不完全相同,它仍然比我在可用默认构造函数时使用的简单for循环复杂得多。
发布于 2015-10-24 15:18:14
std::experimental::optional
或boost等价物的开销并不大,但“这可能是,也可能不是建造的”。
一个不安全的等价物是std::aligned_storage_t
,您可以在那里进行构造。问题正在毁灭,你需要知道它是否被建造。
一个更好的选择可能是选择整个数组,而根本没有零参数ctor。打包构建每个参数所需的内容,创建一个构造函数,而不是一个循环。
template<class T, size_t...Is, class F>
std::array<T,sizeof...(Is)> gen_array(
std::index_sequence<Is...>, F&&f
){
return {{f(Is)...}};
)
template<class T, size_t N, class F>
std::array<T,N> gen_array(
F&&f
){
return gen_array(std::make_index_sequence<N>{}, f);
)
上面的函数调用传递的lambda,其中包含每个元素的索引,以构造元素。
发布于 2015-10-24 15:27:02
如果ThirdPartyLibraryType
没有默认构造函数,则这很可能是由于有效的设计决策/原因造成的。
然后有两种方法:
ThirdPartyLibraryType
的构造,直到知道要使用哪个构造函数和使用哪些参数。第一种方法如下所示:
class MyWrapper {
public:
MyWrapper() : impl(/*parameters that you've selected*/) {};
private:
ThirdPartyLibraryType impl;
};
也许它适合您的需要,因为您已经知道要使用哪个构造函数参数,或者因为您可以负担得起构造一个廉价的对象并在以后重写它。但这并不总是个好主意..。
第二种方法将使用您想要避免的指针。这种方法有许多优点:
事实上,显而易见的指针方法将使包装器实现PIMPL成语。
https://stackoverflow.com/questions/33319649
复制相似问题