我在VS2010-SP1中有下面的类,三元运算符和if-else似乎对getname方法下面的代码有不同的工作方式
template <int size=120> class StringBuf{
public:
StringBuf(const char* src){
strcpy(s,src);
}
// Copy from another StringBuf
StringBuf(const StringBuf& src){
strcpy(s,src.get());
}
// String access
operator const char*() const {return get();}
const char* get() const { return s ; }
private:
char s[size];
};
class MyPony{
StringBuf<10> name;
public:
MyPony(char* name_) : name(name_){}
const char* getname(bool bVal){
//if( bVal )
// return name;
//else
// return "Jimmy";
return (bVal==true) ? name : "Jimmy";
}
};
int main(){
MyPony pony("Pani");
const char* getname = pony.getname(true);
return 0;
}
如果我使用三元运算符getname()方法通过调用复制构造函数生成名称的副本,然后在临时副本上调用运算符const char * .
如果我将三元运算符更改为if-else,则代码只调用运算符const char *而不进行临时副本 .
我的理解是,如果else和三元运算符应该表现相同,但为什么这个类的行为不同?有什么东西我可以忽略吗?
对于三元运算符VS2005似乎直接调用运算符const char * .
1 回答
当然:条件表达式
a ? b : c
的类型是b
和c
的常见类型,在您的情况下是StringBuf<10>
. 因此,在将结果值考虑为return
之前,必须首先将操作数转换为该类型 .条件表达式是一个表达式,
if
语句是一个语句 . 对于不同的目的,它们是不同的东西 . 在您的情况下使用if
语句 .您可能想知道为什么常见类型是
StringBuf<10>
而不是char const *
. 这是因为C 11 5.16 / 3("Conditional operator"),它表示考虑隐式转换 . 在您的情况下,存在从char const [6]
("Jimmy"
的类型)到StringBuf<10>
的隐式转换,但不是相反的方式,因此公共类型是唯一定义的 . 为了比较,如果您尝试x ? name : static_cast<char const *>("Jimmy")
,那将无法编译 .