可以使用C ++模板来延迟对其参数的求值吗?

时间:2018-11-14 01:34:22

标签: c++ templates

我正在使用一个基本具有如下行为的宏的代码库:

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 + bexpensive_op的求值?我可以看到这种情况在其他情况下(例如在嵌入式DSL中)很有用,但是宏看起来很脆弱。

2 个答案:

答案 0 :(得分:2)

如果您不更改语法或修改expensive_op,我认为您的要求是不可能的。基本问题是,无论您做什么,在调用重载运算符时,操作数都已经被求值,因为必须将它们作为参数传递给运算符。我不认为有一种方法可以仅通过在函数实现内部执行某些操作来避免对函数调用的参数求值。因此,不可能有一种方法来实现您的要求...

答案 1 :(得分:2)

没有预处理器就无法做到这一点,并且仍然保持语法。一种微创的变体将需要将调用expensive_op包装在lambda中。

#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); };
}