有条件的操作员从其参数的副本中返回值
Conditional operator returns value from a copy of its argument
当两个返回条件运算符c?x:y
的返回参数不具有相同类型时,在应用铸件之前制作了副本。可以在保持简单的useabiltiy时被阻止吗?
我有这个(修剪问题(:
struct Fixed {
char data[10];
Fixed(char *s) { strcpy(data, s); }
operator char*() { return this->data; }
};
,但条件运算符和nullptr的行为确实很差:
Fixed f =...; // just here to show the type of f, don't read too much into this
...
bool condition = ...;
char *s = condition ? nullptr : f;
制作了F的副本,S现在指出了堆栈上的价值,该价值很快就会消失。这一切都是因为nullptr
的类型是std::nullptr_t
。f
将通过演员 char*
进行,但仅在首先复制之后。这似乎是极差的行为,但这是规格所说的。
我目前的解决方案是使演员和CTOR explicit
,但有点可用性的废墟。还有其他解决方案吗?
这里有一些示例代码(忽略质量,因为我在大量使用此操作时,以查看GCC和LLVM的处理方式不同(:
#include <cstdio>
#include <iostream>
#include <array>
#include <cstring>
using namespace std;
struct A : public array<char,4> {
A() { cerr<<"defn"; }
A(const A &o) { cerr<<"copyn"; (*this)=o;}
A(const char *s) { cerr<<"ctorn";assign(s); } // explicit fixes
void assign(const char*s) {cerr<<"assignn";memset(this->begin(), 0, 4); strncpy(this->begin(), s, 4); }
operator char*() { cerr<<"castn";return this->begin(); }
//operator void*() { cerr<<"voidn";return this->begin(); }
//operator std::nullptr_t() { cerr<<"voidn";return (std::nullptr_t)this->begin(); }
};
volatile A *faraway = new A();
char* plain(A &v) { cerr<<"in pln";
return faraway == nullptr ? nullptr : v;
}
char* cast1(A &v) { cerr<<"in c1n";
return faraway == nullptr ? (char*)nullptr : v;
}
char* cast2(A &v) { cerr<<"in c2n";
return faraway == nullptr ? nullptr : (char*)v;
}
int main() {
A *a = new A; a->assign("asd");
char *x = a->data();
cerr << "nplainn";
char *yp = plain(*a);
cerr << "nc1n";
char *y1 = cast1(*a);
cerr << "nc2n";
char *y2 = cast2(*a);
cerr << "n---n";
cerr << (void*)a << "n" << (void*)(a->data()) << "n" << (void*)x << "n---n";
cerr << (void*)yp << "n" << (void*)y1 << "n" << (void*)y2 << "n";
return 0;
}
您的问题是三元组的操作数具有std::nullptr_t
和struct Fixed
。推论规则将寻找从一种操作数类型到另一种操作数类型以及共同基础类别的转换。没有机会推断char*
。
您可以通过提供
operator std::nullptr_t() = delete
;
相关文章:
- 从python中调用C++函数并获取返回值
- 为什么模板类中的对象不能返回值
- 返回值优化:显式移动还是隐式
- lock_guard是否保护返回值
- 调用CreateProcess()并获取字符串的返回值
- 如何使 windows 命令提示符在C++可执行文件上显示返回值?
- 编译器警告:执行到达值返回函数的末尾而不返回值
- 查找 GCD:并非所有控制路径都返回值
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 将返回值存储在函数指针数组的指针中是如何工作的?
- 如何从 std::thread 返回值
- 将返回值从 exe 传递到 bat,并将其传递给 C# 中的进程
- 方法错误"not all control paths return a value"和方法不返回值
- 如何读取 C++ SAFEARRAY**,该 SAFEARRAY** 是 COM 互操作的结果,其中 C# 返回值为
- 对fread的返回值感到困惑
- 有条件的操作员从其参数的副本中返回值
- 按值副本返回,而不是移动
- 改变字符串的副本并返回值,而不是更改原始字符串
- 通过两个副本返回值
- 用函数返回值初始化std::string,是否有副本