Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板条件编译_C++_Templates_Template Templates_Overriding - Fatal编程技术网

C++ 模板条件编译

C++ 模板条件编译,c++,templates,template-templates,overriding,C++,Templates,Template Templates,Overriding,我不知道我是否使用了正确的策略,但我希望使用带有bool值参数的模板,这样当method1和method2设置为false时,我就不必调用fmethod1或fmethod2。我可以使用动态表来实现这一点,但我刚刚发现我可以使用模板来实现这一点,我对这种语法用法进行了如下培训: #include<iostream> template<bool method1, bool method2> class Caller { public: Caller(cons

我不知道我是否使用了正确的策略,但我希望使用带有bool值参数的模板,这样当method1和method2设置为false时,我就不必调用fmethod1或fmethod2。我可以使用动态表来实现这一点,但我刚刚发现我可以使用模板来实现这一点,我对这种语法用法进行了如下培训:

#include<iostream>

template<bool method1, bool method2>
class Caller {

  public:

    Caller(const float prop1, const float prop2):prop1(prop1),prop2(prop2){;}

    float prop1;
    float prop2;

    bool fmethod1(){
      return prop1;
    }

    bool fmethod2(){
      return prop2;
    }

    void mainMethod(){
      std::cout << "Caller<" << method1 << "," << method2 << ">(" << prop1 << ")" << std::endl;
      std::cout << "fmethod1()" << fmethod1() << std::endl;
      std::cout << "fmethod2()" << fmethod2() << std::endl;
    };

};

template<>
class Caller<true,false> {

  public:
    Caller(const float prop2):prop2(prop2){;}
    float prop2;

    // I can declare here to return true, but this 
    // shouldn't be called in Wrapper, since Wrapper method1 is set  
    // to false (the first "or" on wrapper should be set to true and 
    // compiler shouldn't need this method.)
    bool fmethod1();

    bool fmethod2(){
      return prop2;
    }

    void mainMethod(){
      std::cout << "Caller<true,false>" << std::endl;
      std::cout << "fmethod2()" << fmethod2() << std::endl;
    };

};

template<>
class Caller<false,true> {

  public:
    Caller(const float prop1):prop1(prop1){;}
    float prop1;

    bool fmethod1(){
      return prop1;
    }
    bool fmethod2(); // Same here

    void mainMethod(){
      std::cout << "Caller<false,true>" << std::endl;
      std::cout << "fmethod1()" << fmethod1() << std::endl;
    };

};

template<>
class Caller<false,false> {

  public:
    bool fmethod1(){
      return true;
    }

    bool fmethod2(){
      return true;
    }

    void mainMethod(){
      std::cout << "Caller<false,false>" << std::endl;
      std::cout << "fmethod1()" << fmethod1() << std::endl;
      std::cout << "fmethod2()" << fmethod2() << std::endl;
    };

};

template<template<bool, bool> class holded_t,bool method1, bool method2>
class Wrapper{

  public:
    holded_t<method1,method2> holded;

    Wrapper():holded(holded_t<method1,method2>()){;}
    Wrapper(float prop1):holded(holded_t<method1,method2>(prop1)){;}
    Wrapper(float prop1, float prop2):holded(holded_t<method1,method2>(prop1,prop2)){;}

    void mainMethod(){
      if( !method1 || holded.fmethod1() ){
        if( !method2 || holded.fmethod2() ){
          holded.mainMethod();
        } else {
          std::cout << "holded method2 is false" << std::endl;
        }
      } else {
        std::cout << "holded method1 is false" << std::endl;
      }
    }
};


int main(){

  Wrapper<Caller,false,false> holder_ex_false_false;
  holder_ex_false_false.mainMethod();
  Wrapper<Caller,false,true> holder_ex_false_true(0);
  holder_ex_false_true.mainMethod();
  Wrapper<Caller,true,false> holder_ex_true_false(0);
  holder_ex_true_false.mainMethod();
  Wrapper<Caller,true,true> holder_ex_true_true(0,0);
  holder_ex_true_true.mainMethod();
  Wrapper<Caller,true,true> holder_ex_true_true1(1,0);
  holder_ex_true_true1.mainMethod();
  Wrapper<Caller,true,true> holder_ex_true_true2(0,1);
  holder_ex_true_true2.mainMethod();
  Wrapper<Caller,true,true> holder_ex_true_true3(1,1);
  holder_ex_true_true3.mainMethod();


}
但是我想要一种方法来实现这一点,这样当
包装器不需要时,我就不需要为
调用方实现method1或method2,但是编译器(
gcc
)似乎看不到,当模板属性method1为false时,我将永远不需要fmethod1

我的第一个问题是,这种方法是否比普通的继承
virtual
方法有任何好处,比如:

class Caller{
  public:
    virtual bool fmethod1(){return true;}
    virtual bool fmethod2(){return true;}
}

class CallerMethod1Active: public Caller{
  public:
    float prop1;
    bool fmethod1(){return prop1;}
    bool fmethod2(){return true;}
}
…

和第二,关于如何实现这一思想,而不需要实现<代码>调用方FMED1 ?< /P> < P>您可以考虑奇怪的重复模板模式,并使用静态多态性:

#include <iostream>

template<typename Derived>
class BasicCaller
{
    protected:
    BasicCaller() {}

    public:
    void method() {
        static_cast<Derived*>(this)->method1();
        static_cast<Derived*>(this)->method2();
    }

    protected:
    bool method1() { return false; }
    bool method2() { return false; }
};

class CallNone : public BasicCaller<CallNone> {};

class CallFirst : public BasicCaller<CallFirst>
{
    friend class BasicCaller<CallFirst>;

    protected:
    bool method1() {
        std::cout << "First\n";
        return true;
    }
};

class CallSecond : public BasicCaller<CallSecond>
{
    friend class BasicCaller<CallSecond>;

    protected:
    bool method2() {
        std::cout << "Second\n";
        return true;
    }
};

class CallBoth : public BasicCaller<CallBoth>
{
    friend class BasicCaller<CallBoth>;

    protected:
    bool method1() {
        std::cout << "Both First\n";
        return true;
    }

    bool method2() {
        std::cout << "Both Second\n";
        return true;
    }

};


int main()
{
    std::cout << "CallNone\n";
    CallNone a;
    a.method();
    std::cout << "CallFirst\n";
    CallFirst b;
    b.method();
    std::cout << "CallSecond\n";
    CallSecond c;
    c.method();
    std::cout << "CallBoth\n";
    CallBoth d;
    d.method();
}
#包括
模板
贝西卡尔级
{
受保护的:
BasicCaller(){}
公众:
void方法(){
静态_cast(this)->method1();
静态_cast(this)->method2();
}
受保护的:
bool method1(){return false;}
bool method2(){return false;}
};
类CallNone:public BasicCaller{};
第一堂课:公共基础课
{
朋友级BasicCaller;
受保护的:
布尔方法1(){

std::cout在
包装器中
可以将对
fmethod1
fmethod2
的调用移动到单独的帮助函数中,这些帮助函数仅在存在正确的模板参数时才会实例化:

    void mainMethod(){
      if( testmethod1(std::integral_constant<bool, method1>()) ){
        if( testmethod2(std::integral_constant<bool, method2>()) ){
          holded.mainMethod();
        } else {
          std::cout << "holded method2 is false" << std::endl;
        }
      } else {
        std::cout << "holded method1 is false" << std::endl;
      }
    }
    bool testmethod1(std::true_type) { return holded.fmethod1(); }
    bool testmethod1(std::false_type) { return false; }
    bool testmethod2(std::true_type) { return holded.fmethod2(); }
    bool testmethod2(std::false_type) { return false; }
void main方法(){
if(testmethod1(std::integral_constant()){
if(testmethod2(std::integral_constant()){
holded.main方法();
}否则{

旁注(对不起,我现在没有时间讨论你的问题):您还可以使用枚举来代替布尔模板参数,这将有助于您表达参数的作用:
Caller
Caller
更直观。的确@stefan,我曾考虑过使用枚举,但为了使示例更简单,我一直使用布尔值。无论如何,感谢您的提示!您的
 包装器
needs
fmethod1()
in
holdded.fmethod1()
@Jarod42您是对的,我更改了逻辑,现在它可以工作了…谢谢。很抱歉大家犯了错误…
    void mainMethod(){
      if( testmethod1(std::integral_constant<bool, method1>()) ){
        if( testmethod2(std::integral_constant<bool, method2>()) ){
          holded.mainMethod();
        } else {
          std::cout << "holded method2 is false" << std::endl;
        }
      } else {
        std::cout << "holded method1 is false" << std::endl;
      }
    }
    bool testmethod1(std::true_type) { return holded.fmethod1(); }
    bool testmethod1(std::false_type) { return false; }
    bool testmethod2(std::true_type) { return holded.fmethod2(); }
    bool testmethod2(std::false_type) { return false; }