C++ 在C+;中有没有一种方法可以使用条件进行构造函数委托+;11?
我试图使用C++11委托特性来构造一个以输入值为条件的类。这可能吗?下面的代码在语法上不正确,但我把它放在这里是为了澄清C++ 在C+;中有没有一种方法可以使用条件进行构造函数委托+;11?,c++,c++11,constructor,delegation,C++,C++11,Constructor,Delegation,我试图使用C++11委托特性来构造一个以输入值为条件的类。这可能吗?下面的代码在语法上不正确,但我把它放在这里是为了澄清 enum MyEnum{A,B}; 类型定义结构{ int-val; 髓鞘e; }我的结构; 福班{ 公众: Foo(MyStruct a,MyStruct b){}//a.e==a和b.e==b(已选中断言) Foo(MyStruct x){ 如果(x.e==A){ 返回Foo(x,{0,B}); }否则{ 返回Foo({0,A},x); } } }; 这是一种直接的方法
enum MyEnum{A,B};
类型定义结构{
int-val;
髓鞘e;
}我的结构;
福班{
公众:
Foo(MyStruct a,MyStruct b){}//a.e==a和b.e==b(已选中断言)
Foo(MyStruct x){
如果(x.e==A){
返回Foo(x,{0,B});
}否则{
返回Foo({0,A},x);
}
}
};
这是一种直接的方法。请注意,同一个ctor被委托给,但参数会更改。这与您的示例一致,但可能不是您真正的问题
现在,假设你有一个更复杂的问题。实际上,您希望根据运行时值调用不同的构造函数吗 如果我们希望根据运行时值调用不同的ctor,我们可能必须依赖(希望省略)复制或移动ctor 简单的方法就是
Foo(MyStruct x):
Foo( (x.e==A)?
Foo{x, {0,B}}:
Foo{{0,A}, x}
)
{}
其中,我们根据x.e
使用不同的Foo
调用Foo
复制/移动ctor。这有一个阻塞省略的小问题
这时你应该停下来。因为下一步是相当疯狂的
这里有一种过于花哨的方法来避免构建候选
Foo
s,我认为甚至允许省略(没有任何线索表明编译器是否真的会这样做):
模板
结构延迟构造{
无效常数*数据;
T(*func)(无效常数*);
模板
延迟构造(F常数和F):
数据(&f),
func([](无效常量*ptr)->T{
F const&F=*静态_cast(ptr);
返回f();
})
{}
T运算符()()常量{
返回func(数据);
}
};
结构Foo{
显式Foo(delayed_构造d):Foo(d()){
Foo(MyStruct a,MyStruct b){}
Foo(MyStruct x):
Foo((x.e==A)?
延迟的_构造{[&]()->Foo{
返回{x,{0,B};
}}:
延迟的_构造{[&]()->Foo{
返回{0,A},x};
}}
)
{}
};
这会产生一堆非常复杂的东西,允许您在调用两个不同的CTOR之间进行选择。如果不选择要调用的ctor,则甚至不会计算ctor的参数
delayed_-construct
基本上是一个std::function
,它假定它的生存期是临时的,这样做可能会使编译器更容易进行优化
我相信该标准允许在
Foo(MyStruct x)
中创建的lambdas中构造的Foo
直接构造我们调用它的Foo
。我可能是错的,而且即使我是对的,编译器也很可能不会这么做。对复制或移动ctor的省略调用对于Foo
来说是不可接受的吗?关于MyStruct
?在您的回答中,假设三元运算符?:
的所有三个操作数都是在它只计算第二个或第三个参数的情况下计算的,具体取决于第一个参数的值。它从不计算所有三个操作数。@RalphTandetzky修复了我想。很抱歉,您的大脑出现了问题。模板代码中仍然存在一些错误:必须在操作符()
上删除this
的右值引用。static\u cast
无法丢弃常量。因此,在那里写入static\u cast
。在这些更改之后,您的代码在gcc和clang上以C++11和C++14模式运行。您怎么会认为,移动或复制实际上被删除了?@ralph我认为删除是合法的,因为所有内容都是候选的,并且以复制/移动结束。如果它没有,或者如果我错误地认为它是合法的,我也不会感到惊讶。
Foo(MyStruct x):
Foo( (x.e==A)?
Foo{x, {0,B}}:
Foo{{0,A}, x}
)
{}
template<class T>
struct delayed_construct {
void const* data;
T(*func)(void const*);
template<class F>
delayed_construct( F const& f ):
data(&f),
func([](void const* ptr)->T{
F const& f = *static_cast<F const*>(ptr);
return f();
})
{}
T operator()() const {
return func(data);
}
};
struct Foo {
explicit Foo( delayed_construct<Foo> d ):Foo(d()) {}
Foo(MyStruct a, MyStruct b) {}
Foo(MyStruct x):
Foo( (x.e==A)?
delayed_construct<Foo>{[&]()->Foo{
return {x, {0,B}};
}}:
delayed_construct<Foo>{[&]()->Foo{
return {{0,A}, x};
}}
)
{}
};