Есть ли хороший способ убедиться, что результат функции C ++ не игнорируется?

Недавно я столкнулся со случаем, когда у меня была константная функция-член, выполняющая операцию и возвращающая результат. Например,

class Foo { ...
    Foo add(Foo const & x) const;
}

Но кто-то другой случайно вызвал его, как будто он обновлял объект this (игнорируя результат):

Foo a = ...;
Foo b = ...;
a.add(b);

(Эта ошибка фактически возникла в результате несовершенного рефакторинга.)

Есть ли способ заставить последнюю строку выше вызывать ошибку или предупреждение? Следующим лучшим вариантом будет уловка во время выполнения, которая в основном рассматривается в следующем шаблоне. Однако это убивает оптимизацию возвращаемого значения, что видно по результату счетчика.

template<typename T>
class MustTake {
    T & obj;
    bool took;
public:
    MustTake(T o) : obj(o), took(false) {}
    ~MustTake() { if (!took) throw "not taken"; }
    operator T&() { took = true; return obj;}
};

struct Counter {
    int n;
    Counter() : n(0) {}
    Counter(Counter const & c) : n(c.n+1) {}
    ~Counter() {}
};

Counter zero1() {
    return Counter();
}

MustTake<Counter> zero2() {
    return Counter();
}

int main() {
    Counter c1 = zero1();
    printf("%d\n",c1.n);    // prints 0
    Counter c2 = zero2();
    printf("%d\n",c2.n);    // prints 1
    zero1();    // result ignored
    zero2();    // throws
    return 0;
}

Я полагаю, я могу уменьшить неэффективность, используя макрос, так что MustTake <> будет только отладкой и не будет операцией для выпуска.

I ищу решение времени компиляции. Если это не удается, я ищу лучшее решение для времени выполнения.

7
задан xan 21 June 2011 в 23:48
поделиться