1

For example I have a function call in some code I want to be able to enable/disable as I like.

Normally I could just use an if, but then it would check each time if the function can be ran, which I don't want. I simply want the code to never do that check.

ifdef blocks can be messy and quite dirty, they pile up and make code hard to read.

Can't I solve this with some sort of template ? I know I can make multiple lambdas to build each version of the possible function call I'd want.

Is this what a static if means ? Because in my mind, what I want to do is a self modifying code, which I don't know if it's a good idea or possible at all.

4

4 回答 4

3

假设这个决定需要在运行时做出......

虽然这个问题有很多复杂的解决方案,但函数指针是一种简单的方法(尽管我怀疑它的性能明显优于条件)。

#include <functional>
#include <iostream>

void option1(int) {
    std::cout << "option 1\n";
}

void option2(int) {
    std::cout << "option 2\n";
}

std::function<void(int)> fp(option1);

int main() {
    fp(3);

    // Let's change what fp does:
    fp = option2;
    fp(3);
}
于 2014-07-11T16:11:41.383 回答
2

如果我没有误解您的问题,我认为您需要类似用于运行时决策的策略设计模式。

但是仅仅因为你要求一个模板,这里是一个使用 基于策略的模板元编程的例子...... 但是在这里,决定是在编译时做出的。

struct task {
    void do_task() { /* really do the task... */ }
};

struct no_task {
    void do_task() {} // empty
};

template<typename Task> class host : public Task {};

// here you take the decision...
// you can pass either task or no_task
host<task> h;

// and later you call the function...
h.do_task();

使用模板非常有效。
没有通过任何指向函数的指针的间接性。
编译器很容易内联函数。
如果你通过它no_task,调用站点甚至不会调用空函数(检查一下你的编译器的优化级别)。

于 2014-07-11T16:26:22.760 回答
1

您可以使用函数重载和布尔模板参数:

template<bool B>
class X{
   // Function to be called when B is true
   void foo(std::true_type) {
      ..
   }
   // Function to be called when B is false
   void foo(std::false_type) {
        ... // leave empty to do nothing if B is false
   }



   void bar(){
      // This will call either of the foos depending on B
      foo(std::integral_constant<bool,B>());
   }

}

说明:类型特征std::integral_constant将评估为类型值std::true_typestd::false_type取决于B是真还是假。此类型将用于重载决议,因此编译器将为您选择正确的方法。您可以简单地将其中一个函数定义为空。例如,这就像在B为假时“禁用”呼叫。

调用哪个函数的决定是在编译时完成的,因此您不会为此决定承受运行时开销。

于 2014-07-11T16:09:31.213 回答
1

是的,有一些方法可以做你想做的事,但由于它们是运行时的,它们确实会推断出成本。至于我在下面给出的内容是否比 if... 更快或更慢...您将不得不进行分析并查看。您为取消引用付费,但失去了额外的分支。

函数指针

您可以通过拥有多个版本的函数(或具有虚函数的对象)来解决这个问题。

例子:

void stud(const char *) {}
void _log(const char *msg) { clog << msg << endl; };

void (*log)(const char *) = stud; 

void enable_logging()  { log = _log; }
void disable_logging() { log = stud; }

int main() {
    log("This will not be logged");
    enable_logging();
    log("This will be logged.");
}
于 2014-07-11T16:18:35.397 回答