C++ 有条件地实例化具有已删除默认构造函数的类
考虑一个具有已删除默认构造函数的类(我的实际类要复杂得多,默认构造函数被隐式删除,因为它的一个成员具有已删除的默认构造函数)。我想根据一些输入的值用一个构造函数实例化我的类,然后做“一系列的事情”。 下面的代码显示了由于代码注释中所述的原因而无法实现的两种方法,但给出了我试图实现的想法C++ 有条件地实例化具有已删除默认构造函数的类,c++,scope,instantiation,C++,Scope,Instantiation,考虑一个具有已删除默认构造函数的类(我的实际类要复杂得多,默认构造函数被隐式删除,因为它的一个成员具有已删除的默认构造函数)。我想根据一些输入的值用一个构造函数实例化我的类,然后做“一系列的事情”。 下面的代码显示了由于代码注释中所述的原因而无法实现的两种方法,但给出了我试图实现的想法 #include <vector> class A { bool m_with_v; int m_i; std::vector<double> m_v; publi
#include <vector>
class A {
bool m_with_v;
int m_i;
std::vector<double> m_v;
public:
A() = delete;
A(int i) : m_i(i), m_with_v(false) {}
A(int i, std::vector<double> v) : m_i(i), m_v(v), m_with_v(true) {}
auto do_stuff() { /* do stuff depending on m_with_v */ };
};
int main(int argc, char* argv[])
{
bool yes_no;
/* Obtain a value for yes_no from argv */
A a; // the default constructor of "A" cannot be referenced -- it is a deleted function
if (yes_no)
a = A(1);
else {
std::vector<double> v{ 1,2,3 };
a = A(1, v);
}
a.do_stuff();
// do a bunch more things
if (yes_no)
A b(1);
else {
std::vector<double> v{ 1,2,3 };
A b(1, v);
}
b.do_stuff(); // identifier "b" is undefined, i.e. it's gone out of scope
// do a bunch more things
}
#包括
甲级{
带v的bool m_;
国际货币基金组织;
std::向量m_v;
公众:
A()=删除;
A(inti):m_i(i),m_与v(false){}
A(inti,std::vectorv):m_i(i),m_v(v),m_with_v(true){}
auto do_stuff(){/*根据m_和{u v*/}进行操作;
};
int main(int argc,char*argv[])
{
布尔是/否;
/*从argv获取yes\u no的值*/
A;//无法引用“A”的默认构造函数——它是一个已删除的函数
如果(是/否)
a=a(1);
否则{
std::向量v{1,2,3};
a=a(1,v);
}
a、 做某事;
//做更多的事情
如果(是/否)
A b(1);
否则{
std::向量v{1,2,3};
A b(1,v);
}
b、 do_stuff();//标识符“b”未定义,即超出范围
//做更多的事情
}
一个明显的方法是在if
块的每个部分中移动“一堆东西”,但这会导致大量重复的代码,这是我想要避免的
另一个明显的方法是创建一个函数来完成“一堆事情”,并在if
块的每个部分调用它,但这需要一定量的重构,如果需要向函数调用传递大量变量,函数调用可能会变得相当丑陋
因此,我的问题是:是否有某种方法可以有条件地实例化我的类并使其在周围的作用域中可用?您可以使用条件运算符实例化它:
A a = yes_no ? A(1) : A(1, {1,2,3});
a.do_stuff();
等等。您可以让一个自由函数(可能是静态的,在a::,R Sahu支持自由函数)返回一个适当的a
A a = buildA(yes_no);
buildA将是
A buildA(bool yes_no){
if (yes_no)
return A(1);
> .P> >可以考虑使用<代码> UNQuyGyPTR而不是<代码> Reale>代码>方法(这是自C++ 14以来可用的)。在这种情况下,您将把
ptrA=std::make_唯一(1)代码>
另一种选择是使用三元运算符aa=(yes\u no)?A(1):A(1,{1,2,3})
或者按照其他人的建议,将对象创建逻辑提取到一个单独的函数中,在该函数中,您可以根据yes\u no
条件的实现,从if
块返回对象 auto a=[&]{
auto a = [&]{
if (yes_no) {
return A(1);
} else {
std::vector<double> v{ 1,2,3 };
return A(1, v);
}
}();
a.do_stuff();
如果(是/否){
返回A(1);
}否则{
std::向量v{1,2,3};
返回A(1,v);
}
}();
a、 做某事;
没有必要用额外的逻辑污染A
。最好将其作为非成员函数。虽然juanchopanza的解决方案更简单地回答了我的问题,但我最终将此解决方案用作向量v
,它是非平凡生成的,并且只需要为构造函数的选择而生成,不会污染周围的范围。因为C++14,考虑使用=make_unique(args)
而不是.reset(newa(args))
auto a = [&]{
if (yes_no) {
return A(1);
} else {
std::vector<double> v{ 1,2,3 };
return A(1, v);
}
}();
a.do_stuff();