C++ std::make#u共享三值返回';不编译
我正在使用VisualStudio2010并使用factory创建抽象基类的两个实现之一。factory Create方法接受bool标志,并在共享的\u ptr中返回两个impl中的一个。使用if语句对我来说很好,但是当我尝试使用带有make_共享调用的三元语句时,编译器会抱怨C++ std::make#u共享三值返回';不编译,c++,visual-studio-2010,factory,ternary-operator,C++,Visual Studio 2010,Factory,Ternary Operator,我正在使用VisualStudio2010并使用factory创建抽象基类的两个实现之一。factory Create方法接受bool标志,并在共享的\u ptr中返回两个impl中的一个。使用if语句对我来说很好,但是当我尝试使用带有make_共享调用的三元语句时,编译器会抱怨 class Base { public: Base() {}; }; class Foo : public Base { public: Foo() {}; }; class Bar : public
class Base {
public:
Base() {};
};
class Foo : public Base {
public:
Foo() {};
};
class Bar : public Base {
public:
Bar() {};
};
class Factory {
public:
static std::shared_ptr<Base> Create(bool isFoo) {
return isFoo ?
std::make_shared<Foo>() :
std::make_shared<Bar>();
}
};
int main() {
std::shared_ptr<Base> instance = Factory::Create(true);
return 0;
}
类基{
公众:
Base(){};
};
Foo类:公共基础{
公众:
Foo(){};
};
分类栏:公共基础{
公众:
Bar(){};
};
阶级工厂{
公众:
静态标准::共享ptr创建(bool-isFoo){
返回isFoo?
std::使_共享():
std::使_共享();
}
};
int main(){
std::shared_ptr instance=Factory::Create(true);
返回0;
}
VS给出的错误是
'没有可执行此转换的用户定义的转换运算符,或者无法调用该运算符
c:\path\file.h(78):错误C2668:“std::tr1::shared\u ptr::shared\u ptr”:对重载函数的调用不明确
具有
[
_Ty=基础
]
注意
static std::shared_ptr<Base> Create(bool isFoo) {
if (isFoo)
return std::make_shared<Foo>();
return std::make_shared<Bar>();
}
static std::shared_ptr Create(bool-isFoo){
if(isFoo)
返回std::make_shared();
返回std::make_shared();
}
编译得很好。这是因为三元运算中的第二个和第三个表达式必须相互转换。在您的情况下,
std::shared_ptr
不能转换为std::shared_ptr
,反之亦然
虽然它们都可以转换为
std::shared_ptr
,但它们不能相互转换。std::make_shared()的返回类型为std::shared_ptr
两个derived都可转换为它们的基类,因此两个
共享的ptr
s都可以转换为共享的ptr
,但三元运算符希望其第二个和第三个参数已经具有相同的类型,或者,正好其中一个可以转换为另一个。当三值条件运算符的第二个和第三个操作数有两种不同的类类型时,通常必须能够将其中一个转换为另一个。如果两者都不能转换为另一种,则程序将无法编译,即使存在第三种类型,这两种类型都可以转换为,如本例所示
解决方案:
return isFoo ?
std::shared_ptr<Base>(std::make_shared<Foo>()) :
std::shared_ptr<Base>(std::make_shared<Bar>());
返回isFoo?
std::shared_ptr(std::make_shared()):
std::shared_ptr(std::make_shared());
正如您的注释所示,问题在于三元运算符。每个表达式(甚至像A=1的类)都有C++的类型。在您的示例中,编译器必须尝试推导表达式isFoo?std::make_shared():std::make_shared()代码>通常编译器会查找对第二个和第三个操作数都有效的类型(本例中的make_共享调用)。VS试图在其错误消息中告诉您的是,它找不到公共类型
相反,if语句之所以有效,是因为make_共享调用是两个独立的表达式,因此不需要公共类型