参照によって比較される型を作成する方法はありますが、関数で作成できないことを強制します (スタック/削除されたオブジェクトへの参照を防ぎます)。
関数内で「return Error::New(...)」を実行できることに気付くまで、私は以下のエラー型を思いつき、それを誇りに思っていました。問題は h() 関数にあります。
#include <stdio.h>
#include <string.h>
#include <string>
using namespace std;
class Error {
std::string _str;
const Error &from;
Error();
Error(const char *s)
: _str(s), from(*this)
{
}
public:
Error(const Error &err)
: from(err.from)
{
}
static Error New(const char *s) {
return Error(s);
}
bool operator== (const Error &rhs) const {
return (&from == &rhs.from);
}
bool operator!= (const Error &rhs) const {
return (&from != &rhs.from);
}
std::string ToString() {
return from._str;
}
public:
static const Error None;
};
const Error Error::None("none");
// user errors
auto ErrConnect = Error::New("failed to connect");
auto ErrWrite = Error::New("invalid write");
Error f() {
return ErrConnect;
}
Error g() {
return Error::None;
}
Error h() {
return Error::New("test");
}
int main()
{
printf("ErrConnect == ErrConnect : %d\n", ErrConnect == ErrConnect);
printf("ErrConnect == ErrWrite : %d\n", ErrConnect == ErrWrite);
printf("f() == ErrConnect : %d\n", f() == ErrConnect);
printf("f() == ErrWrite : %d\n", f() == ErrWrite);
printf("f() != ErrConnect : %d\n", f() != ErrConnect);
printf("f() != ErrWrite : %d\n", f() != ErrWrite);
printf("f() == Error::None : %d\n", f() == Error::None);
printf("f() != Error::None : %d\n", f() != Error::None);
printf("g() == Error::None : %d\n", g() == Error::None);
printf("g() != Error::None : %d\n", g() != Error::None);
printf("f().ToString() : %s\n", f().ToString().c_str());
printf("ErrConnect.ToString() : %s\n", ErrConnect.ToString().c_str());
auto err = f();
auto err2 = err;
auto err3 = err2;
printf("err3 == ErrConnect : %d\n", err3 == ErrConnect);
auto err4 = h();
printf("err4 from h() : %s\n", err4.ToString().c_str());
}