C++ 是否有一个C++;与运行时#ifdef近似等效的编程技术?

C++ 是否有一个C++;与运行时#ifdef近似等效的编程技术?,c++,templates,static-if,C++,Templates,Static If,例如,我在一些代码中有一个函数调用,我希望能够根据自己的喜好启用/禁用 通常我可以使用if,但是每次它都会检查函数是否可以运行,这是我不想要的。我只是希望代码永远不要做那个检查 如果DEF块很凌乱,很脏,它们会堆积起来,使代码难以阅读 我不能用某种模板来解决这个问题吗?我知道我可以创建多个lambda来构建我想要的可能函数调用的每个版本 这就是静态if的意思吗?因为在我看来,我想做的是一个自我修改的代码,我不知道这是一个好主意还是可能的。你可以使用函数重载和布尔模板参数: template<

例如,我在一些代码中有一个函数调用,我希望能够根据自己的喜好启用/禁用

通常我可以使用if,但是每次它都会检查函数是否可以运行,这是我不想要的。我只是希望代码永远不要做那个检查

如果DEF块很凌乱,很脏,它们会堆积起来,使代码难以阅读

我不能用某种模板来解决这个问题吗?我知道我可以创建多个lambda来构建我想要的可能函数调用的每个版本


这就是静态if的意思吗?因为在我看来,我想做的是一个自我修改的代码,我不知道这是一个好主意还是可能的。你可以使用函数重载和布尔模板参数:

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

}
模板
X类{
//当B为true时要调用的函数
void foo(标准::真实类型){
..
}
//当B为false时要调用的函数
void foo(标准::错误类型){
…//如果B为false,则保留为空以不执行任何操作
}
空条(){
//这将调用任意一个foo,具体取决于B
foo(std::integral_constant());
}
}
说明:根据
B
是真还是假,类型特征
std::integral_常量
将计算为类型
std::true_type
std::false_type
的值。此类型将用于重载解析,因此编译器将为您选择正确的方法。您可以简单地将其中一个函数定义为空。例如,这类似于在
B
为false时“禁用”调用


要调用哪个函数的决定是在编译时完成的,因此此决定不会产生运行时开销。

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

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

}
模板
X类{
//当B为true时要调用的函数
void foo(标准::真实类型){
..
}
//当B为false时要调用的函数
void foo(标准::错误类型){
…//如果B为false,则保留为空以不执行任何操作
}
空条(){
//这将调用任意一个foo,具体取决于B
foo(std::integral_constant());
}
}
说明:根据
B
是真还是假,类型特征
std::integral_常量
将计算为类型
std::true_type
std::false_type
的值。此类型将用于重载解析,因此编译器将为您选择正确的方法。您可以简单地将其中一个函数定义为空。例如,这类似于在
B
为false时“禁用”调用

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

假设此决定需要在运行时做出。。。 虽然这个问题有很多复杂的解决方案,但函数指针是一种简单的方法(尽管我怀疑它的性能是否比条件指针好得多)

#包括
#包括
无效选项1(内部){
std::cout假设需要在运行时做出此决定。。。
虽然这个问题有很多复杂的解决方案,但函数指针是一种简单的方法(尽管我怀疑它的性能是否比条件指针好得多)

#包括
#包括
无效选项1(内部){

std::cout是的,有很多方法可以满足您的需求,但由于它们是运行时的,因此它们确实可以推断出成本。至于我下面给出的是比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.");
}
void螺柱(常量字符*){

void_log(const char*msg){clog是的,有很多方法可以做你想做的事情,但是由于它们是运行时的,它们确实可以推断出一个成本。至于我下面给出的是比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.");
}
void螺柱(常量字符*){

void{u log(const char*msg){clog如果我没有误解您的问题,我想您需要类似的东西,它用于运行时决策

但是,仅仅因为您需要一个模板,下面是一个使用 但在这里,决定是在编译时做出的

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();
struct任务{
void do_task(){/*确实执行任务…*/}
};
结构无任务{
void do_task(){}//empty
};
模板类主机:公共任务{};
//这是你的决定。。。
//您可以通过任务或不通过任务
宿主h;
//然后调用函数。。。
h、 dou_task();
使用模板非常有效。
没有通过任何指向函数的指针进行间接寻址。
编译器很容易内联函数。

如果您将其传递给
no_task
,调用站点甚至不会调用空函数(请查看您的编译器的优化级别)。

如果我没有误解您的问题,我想您需要类似于which for runtime决策的东西

但是,仅仅因为您需要一个模板,下面是一个使用 但在这里,决定是在编译时做出的

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();
struct任务{
void do_task(){/*确实执行任务…*/}
};
结构无任务{
void do_task(){}//empty
};
模板类主机:公共任务{};
//这是你的决定。。。
//您可以通过任务或不通过任务
宿主h;
//然后调用函数。。。
h、 dou_task();
使用模板非常有效。
没有通过任何指向函数的指针进行间接寻址。
编译器很容易理解