我有一个类型 T
由外部库和我的虚拟成员函数提供f
声明如下,在我的程序中被许多类型覆盖:
virtual T MyType1::f(input_t in);
virtual T MyType2::f(input_t in);
virtual T MyType3::f(input_t in);
现在我需要一种方法来返回替代的“互斥”信息 - 这与 T
无关- 根据 in
的特定值给调用者.我无法在 T
的域中返回任何特殊值不幸的是,恐怕我将不得不重构 f()
的声明.
我看到了这些可能性:
- 重构
T
作为W MyType::f(input_t)
, 其中W
是一个包装器 周围T
,再加上另一个成员数据和一个转换运算符到T
所以 我可以使用W
作为T
到处都像以前一样,除了少数 我需要检查u
值的地方,例如struct W {T t; U u; operator T();};
- 重构
T
作为variant <T, U>
- 重构
f
作为T MyType::f(input_t in, U& out);
- 重构
f
作为std::tuple<T, U> MyType::f(input_t);
我认为使用变体是最好的选择。你怎么看?
最佳答案
合并 1 和 2:
你得到了你自己的类型之一的抽象,你可以更好地记录和测试结果类型的不变量,你可以根据 variant<T,U>
实现你的结果类型抽象。 .
比较这两段代码的客户端代码:
struct W
{
operator T& (); // throws T_not_generated
bool succeeeded() const;
private:
variant <T, U> data;
};
virtual W MyType1::f(input_t in);
客户端代码:
MyType1 a;
T t1 = a.f(in);
auto r2 = a.f(in);
if(r2.succeeded())
{
T t2 = r2;
}
有了这个:
virtual variant <T, U> MyType1::f(input_t in);
客户端代码:
MyType1 a;
try
{
auto T1 boost::get<T>(a.f(in));
auto r2 = a.f(in);
if(??)
{
T t2 = boost::get<T>(r2);
}
}
catch(const boost::<what's the error type?>& error)
{
///...
}
我的观点是 (tldr):你应该考虑抽象出结果的处理(并强加任何你需要的不变量),但你仍然可以在幕后使用 boost::variant .
关于c++ - 重构返回多个 "informations",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35335953/