Блог пользователя bogorodniy

Автор bogorodniy, история, 4 года назад, По-русски

I wondered for a long time how to make different user-operators. For example write this x minEqual y instead of x = min(x, y)

So recently I've done this, and decided to share it with you.

#include <bits/stdc++.h>

using namespace std;
struct mineq_operator
{
    int tempVal=1000;
    inline mineq_operator operator<<(int& x)
    {
        this->tempVal = x;
        return *this;
    } inline mineq_operator operator>>(int& x)
    {
        x = min(x, tempVal);
        return *this;
    }
};
mineq_operator __me;
inline void operator<<(int& x, mineq_operator& b)
{
    b.tempVal = x;
}
#define minEqual <<__me;__me>>
signed main()
{
    int x = 3, y = 2;
    y minEqual x;
    cout << x << ' ' << y << endl;
}

For use it like x = min(x, y); just write y minEqual x;

And this in compressed format:

#include <bits/stdc++.h>

using namespace std;
struct mineq_operator {int tempVal=1000;inline mineq_operator operator<<(int& x) {this->tempVal = x;return *this;}inline mineq_operator operator>>(int& x) {x = min(x, tempVal);return *this;}};
mineq_operator __me; inline void operator<<(int& x, mineq_operator& b) {b.tempVal = x;}
#define minEqual <<__me;__me>>
signed main() {
  int x = 3, y = 2;
    y minEqual x;
    cout << x << ' ' << y << endl;
}

  • Проголосовать: нравится
  • +61
  • Проголосовать: не нравится

»
4 года назад, # |
  Проголосовать: нравится +23 Проголосовать: не нравится

wow thx, it is very useful!!

»
4 года назад, # |
  Проголосовать: нравится +1 Проголосовать: не нравится

Auto comment: topic has been translated by bogorodniy (original revision, translated revision, compare)

»
4 года назад, # |
  Проголосовать: нравится +4 Проголосовать: не нравится

very cool!

»
4 года назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Some time ago I wrote

/*
/in/ shortcut
+ 2 in [1,2,3]
+ "ab" in "bacaba"
+ 'w' in "cow"
+ "key" in {"key": 123}_json
+ 42 in map<int, string>, set<int> (+unordered)
*/
namespace ultra {
    template<typename T>
    struct in_prefix_t {
        T const *pvalue = nullptr;
        explicit inline in_prefix_t(T const *pvalue) : pvalue(pvalue) { }
    };
    struct in_helper_t { };

} // namespace ultra

ultra::in_helper_t in;

template<typename T>
inline ultra::in_prefix_t<T> operator / (T const& value, ultra::in_helper_t) {
    return ultra::in_prefix_t<T>(&value);
}

template<typename T, typename Container>
inline bool operator / (ultra::in_prefix_t<T> prefix, Container const& cont) {
    return std::find(std::begin(cont), std::end(cont), *prefix.pvalue) != std::end(cont);
}

template<typename T>
inline bool operator / (ultra::in_prefix_t<T> prefix, std::string const& s) {
    return s.find(*prefix.pvalue) != string::npos;
}

inline bool operator / (ultra::in_prefix_t<char> prefix, std::string const& s) {
    return s.find(*prefix.pvalue) != string::npos;
}

template<typename T, typename U, typename V>
inline bool operator / (ultra::in_prefix_t<T> prefix, std::map<U, V> const& m) {
    return m.find(*prefix.pvalue) != m.end();
}

template<typename T, typename U>
inline bool operator / (ultra::in_prefix_t<T> prefix, std::set<U> const& s) {
    return s.find(*prefix.pvalue) != s.end();
}

template<typename T, typename U, typename V>
inline bool operator / (ultra::in_prefix_t<T> prefix, std::unordered_map<U, V> const& m) {
    return m.find(*prefix.pvalue) != m.end();
}

template<typename T, typename U>
inline bool operator / (ultra::in_prefix_t<T> prefix, std::unordered_set<U> const& s) {
    return s.find(*prefix.pvalue) != s.end();
}

template<typename T>
inline bool operator / (ultra::in_prefix_t<T> prefix, json s) {
    return s.count(*prefix.pvalue) != 0;
}

Pretty useless although :)

»
4 года назад, # |
  Проголосовать: нравится +24 Проголосовать: не нравится

Interesting idea, execution leaves much to be desired.

1) You shouldn't put int& as the parameter type for operator>>, int will do just fine. In fact, you'll get compilation errors if you try to use an r-value as an operand, as in the example below.

2) After replacing int& with int, what does this print?

int computeSomething() {
	int z = 1000;
	z minEqual 100;
	return z;
}

signed main() {
  int x = 200, y = 300;
  y minEqual computeSomething();
  cout << x << ' ' << y << endl;
}
»
4 года назад, # |
Rev. 2   Проголосовать: нравится +11 Проголосовать: не нравится

I made it a bit shorter (and also without bug, which ivan100sic mentioned)

Code

And this can be improved to work with any type:

Code

Actually, it is better to use operator ,, instead of operator ^ to avoid extra brackets (link)

By the way, my code creates structure on each minEqual, so probably it is slower than the original version, but I am not sure. However, if you aim for speed, you shouldn't use any of these options, I think.

»
4 года назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

I suppose that I write x minEqual f(1, 2, 3); to minimize x by a result of function call f(1, 2, 3). Obviously it 1) will not compile and 2) might lead to undefined behavior if f(int, int, int) uses minEqual operator as well.

So that I just return to simpler alternative:

void minimize(int& a, int b)
{
    a = std::min(a, b);
}
...
    minimize(x, f(1, 2, 3));
...
»
4 года назад, # |
  Проголосовать: нравится 0 Проголосовать: не нравится

An I use

template<class _A_, class _B_>
void minimize(_A_ &_a_, _B_ _b_) { if (_a_ > _b_) _a_ = _b_; }
bool   ismini(_A_ &_a_, _B_ _b_) { if (_a_ > _b_) { _a_ = _b_; return true; } return false; }

»
4 года назад, # |
Rev. 2   Проголосовать: нравится +1 Проголосовать: не нравится

And I use normal functions like these

/// I use _x_ instead of normal x to prevent from IntelliSense

/// a = min(a, b)
template<class _A_, class _B_>
void minimize(_A_ &_a_, const _B_ &_b_) { if (_a_ > _b_) _a_ = _b_; }

/// return true if (a is minimized to b)
template<class _A_, class _B_>
bool   ismini(_A_ &_a_, const _B_ &_b_) { if (_a_ > _b_) { _a_ = _b_; return true; } return false; }

/// a = min{b, ...}
template<class _A_, class _B_, class..._V_>
void minimize(_A_ &_a_, const _B_ &_b_, const _V_&..._v_) {
    minimize(_a_, _b_);
    minimize(_a_, _v_...);
}