C++ 运算符>> 使用 Mutator 重载?
C++ Operator>> Overloading with Mutator?
我正在尝试找出一种方法(如果可能的话)来重载 >> 运算符以使其与增变器一起正常运行。比如我想写:
myClass obj;
cin >> obj.setValue;
并让它在一行中使用可用的修改器正确设置 obj 的私有值。我知道我可以使用一个临时变量来存储 cin 并用它设置 obj 值,但我想知道是否有更简洁的方法,比如这个。我是一名新手程序员,所以这是我在 myClass 中的徒劳尝试:
friend std::istream &operator>>(std::istream &in, void (myClass::*pt)(double newValue)) {
double temp;
in >> temp;
pt(temp);
return in;
}
我知道我可以简单地重载整个 myClass 以接受:
cin >> myClass;
但这会阻止我在不同时间在 myClass 中设置不同的个人值。
谢谢
cin >> obj.setValue
或 cin >> &obj.setValue
是 无效 C++ 的示例。无法将 reference/pointer 获取到 class
.
的特定实例的 成员函数
你可以做的是将 this
指针和一个 指向成员函数 的指针打包在一个小的 struct
中,然后重载 operator>>
而不是:
template <typename T, typename Arg>
struct setter_t
{
T* _this;
void (T::*_ptr)(Arg);
};
template <typename T, typename Arg>
auto setter(T& x, void (T::*ptr)(Arg))
{
return setter_t<T, Arg>{&x, ptr};
}
template <typename T, typename Arg>
std::istream &operator>>(std::istream &in, setter_t<T, Arg> s)
{
Arg temp;
in >> temp;
(s._this->*s._ptr)(temp);
return in;
}
用法:
myClass obj;
std::cin >> setter(obj, &myClass::setValue);
这是一个 C++17 解决方案,它不会在 setter_t
中不必要地存储 _ptr
。用法:
std::cin >> setter<&myClass::setValue>(obj);
您可以使 .setValue() return 成为对 Functor 的非 const 引用(class 覆盖 operator() ),然后使该 Functor 覆盖
std::istream &operator>>(std::istream &is, MySetterFunctor &x){
double temp;
is >> temp;
x(temp);
return is;
}
仿函数将由 obj 初始化,接收一个指向 obj 的指针并在其内部使用实际 obj 的 setter 方法
void operator()(double v){ obj->set_value(v);}
对于额外的 hackery,您可以将 setValue 设置为非常量 public 成员,这样您就可以像 std::cin >> obj.setValue 那样调用它,并且通常也可以这样做x.setValue(someDouble)。您可以使 obj.set_value 成为受保护的成员函数,并使 MySetterFunctor 成为 obj.class 的友元。
class Obj{
public:
friend class MySetterFunctor;
MySetterFunctor setValue;
...
}
重要免责声明:这都是理论性的谈话,我不确定有人会想要这样做,但我相信它会让你做你想做的。
我正在尝试找出一种方法(如果可能的话)来重载 >> 运算符以使其与增变器一起正常运行。比如我想写:
myClass obj;
cin >> obj.setValue;
并让它在一行中使用可用的修改器正确设置 obj 的私有值。我知道我可以使用一个临时变量来存储 cin 并用它设置 obj 值,但我想知道是否有更简洁的方法,比如这个。我是一名新手程序员,所以这是我在 myClass 中的徒劳尝试:
friend std::istream &operator>>(std::istream &in, void (myClass::*pt)(double newValue)) {
double temp;
in >> temp;
pt(temp);
return in;
}
我知道我可以简单地重载整个 myClass 以接受:
cin >> myClass;
但这会阻止我在不同时间在 myClass 中设置不同的个人值。
谢谢
cin >> obj.setValue
或 cin >> &obj.setValue
是 无效 C++ 的示例。无法将 reference/pointer 获取到 class
.
你可以做的是将 this
指针和一个 指向成员函数 的指针打包在一个小的 struct
中,然后重载 operator>>
而不是:
template <typename T, typename Arg>
struct setter_t
{
T* _this;
void (T::*_ptr)(Arg);
};
template <typename T, typename Arg>
auto setter(T& x, void (T::*ptr)(Arg))
{
return setter_t<T, Arg>{&x, ptr};
}
template <typename T, typename Arg>
std::istream &operator>>(std::istream &in, setter_t<T, Arg> s)
{
Arg temp;
in >> temp;
(s._this->*s._ptr)(temp);
return in;
}
用法:
myClass obj;
std::cin >> setter(obj, &myClass::setValue);
这是一个 C++17 解决方案,它不会在 setter_t
中不必要地存储 _ptr
。用法:
std::cin >> setter<&myClass::setValue>(obj);
您可以使 .setValue() return 成为对 Functor 的非 const 引用(class 覆盖 operator() ),然后使该 Functor 覆盖
std::istream &operator>>(std::istream &is, MySetterFunctor &x){
double temp;
is >> temp;
x(temp);
return is;
}
仿函数将由 obj 初始化,接收一个指向 obj 的指针并在其内部使用实际 obj 的 setter 方法 void operator()(double v){ obj->set_value(v);}
对于额外的 hackery,您可以将 setValue 设置为非常量 public 成员,这样您就可以像 std::cin >> obj.setValue 那样调用它,并且通常也可以这样做x.setValue(someDouble)。您可以使 obj.set_value 成为受保护的成员函数,并使 MySetterFunctor 成为 obj.class 的友元。
class Obj{
public:
friend class MySetterFunctor;
MySetterFunctor setValue;
...
}
重要免责声明:这都是理论性的谈话,我不确定有人会想要这样做,但我相信它会让你做你想做的。