Можно ли использовать шаблоны C ++, чтобы отложить оценку своих аргументов? - PullRequest
0 голосов
/ 14 ноября 2018

Я работаю над кодовой базой, в которой есть макрос, который ведет себя примерно так:

struct to_void {
    template<class T>
    inline void operator&&(T&& t) {}
};

#define cout_if(c) (!(c)) ? ((void)0) : to_void() && std::cout

// --

extern int expensive_op(int c);
void foo(int a, int b) {
    cout_if(a < b) << expensive_op(a + b);
}

Можно ли создать шаблон, который сохраняет синтаксис cout_if, а также предотвращает оценку a + b и expensive_op, если они не нужны? Я вижу, что подобные вещи полезны в других контекстах (например, во встроенных DSL), но макрос кажется хрупким.

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Невозможно сделать это без препроцессора и все еще поддерживать синтаксис.Минимально инвазивный вариант потребовал бы заключить вызов в expensive_op в лямбду.

#include <iostream>

extern int expensive_op(int c);

class cout_if {
    bool m_b;
public:
    cout_if(bool b) : m_b{b} {};
    template <typename T>
    std::ostream& operator<<(T&& rhs) {
        if (m_b) { return std::cout << rhs(); }
        return std::cout;
    }
};

void foo(int a, int b) {
    cout_if(a < b) << [a,b] { return expensive_op(a + b); };
}
0 голосов
/ 14 ноября 2018

Я не думаю, что то, что вы просите, возможно без изменения синтаксиса или изменения expensive_op.Основная проблема заключается в том, что независимо от того, что вы делаете, к тому времени, когда вызывается перегруженный оператор, операнды уже оценены, так как они должны быть переданы в качестве аргументов функции оператора.Я не думаю, что есть способ избежать оценки аргумента вызова функции, просто делая что-то внутри реализации функции.Следовательно, не может быть способа достичь того, о чем вы просите ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...