我有一个对象“a”,我想把它复制到一个对象“b”中但是稍微修改它而不修改“a”。那就是这样的:
class SomeClass{
public:
int a;
public:
SomeClass(int _a) {a = _a;}
SomeClass& doStuff() {++a; return *this;}
};
const SomeClass a( 25);
const auto b = SomeClass( a).doStuff();
这很好用但是我现在/我不想写“a”的类型,然后我想出了这个解决方案:
const auto b = std::remove_const<decltype( a)>::type( a).doStuff();
我这样做了吗?对此有一个不那么难看的解决方案吗? (我不必两次输入“a”。)使用汽车或其他东西。最好不要宏。
答案 0 :(得分:5)
怎么样
template<typename T>
T copy(const T& t) { return T(t); }
const auto b = copy(a).doStuff();
答案 1 :(得分:1)
阐述VTT的评论:
class SomeClass;
class DoStuff
{
friend class SomeClass;
SomeClass const& c;
public:
explicit DoStuff(SomeClass const& c)
: c(c)
{ }
};
class SomeClass
{
int a;
public:
SomeClass(int a)
: a(a)
{ }
SomeClass(SomeClass const& other)
: a(other.a)
{ }
SomeClass(DoStuff d)
: SomeClass(d.c)
{
doStuff();
}
};
SomeClass const a(7);
SomeClass const b((DoStuff(a)));
唯一不幸的缺点:我们需要额外的括号来防止b被解释为函数SomeClass const b (DoStuff a) { }
,a
作为参数名...
我个人更倾向于将DoStuff作为SomeClass的内部类,但这会迫使你再次重复类名:
SomeClass const b (( SomeClass::DoStuff(d) ));
(哈哈,现在我得到了自己 - 一个重复一个类名,即使没有内部类,我仍然有...)
好的,在有人呻吟之前:
SomeClass const b { DoStuff(a) };
最近提到过?好吧,猜测,我个人绝对不会不欣赏这种语法并尽可能避免使用它 - 即使使用初始化列表,我仍然会在括号内放置括号:std::vector<int> v({7, 10, 12});
- 但这是一个不同的主题...
答案 2 :(得分:1)
更好的方法是为专用于SomeClass
操作的doStuff
引用创建一个可分辨的包装器类型,并使构造函数接受此类型。此方法消除了创建临时SomeClass
对象以及将额外参数传递到构造函数的可能开销。虽然SomeClass
相当简单,但没有多大区别。
class
t_DoingStuffSomeClassWrap final
{
#pragma region Fields
private: SomeClass const & m_inst;
#pragma endregion
private:
t_DoingStuffSomeClassWrap(void) = delete;
public:
t_DoingStuffSomeClassWrap(t_DoingStuffSomeClassWrap const & that) noexcept
: m_inst{that.m_inst}
{}
public: explicit
t_DoingStuffSomeClassWrap(SomeClass const & inst) noexcept
: m_inst{inst}
{}
private: t_DoingStuffSomeClassWrap &
operator =(t_DoingStuffSomeClassWrap const & that) = delete;
private: t_DoingStuffSomeClassWrap &
operator =(t_DoingStuffSomeClassWrap && that) = delete;
public: SomeClass const &
Unwrap(void) const noexcept
{
return(m_inst);
}
};
// inside of SomeClass definition:
public: explicit
SomeClass(t_DoingStuffSomeClassWrap const wrap)
: a{wrap.Unwrap().a}
{
doStuff();
}
// actual use
const SomeClass b{t_DoingStuffSomeClassWrap{a}};