C++ 模板条件编译
我不知道我是否使用了正确的策略,但我希望使用带有bool值参数的模板,这样当method1和method2设置为false时,我就不必调用fmethod1或fmethod2。我可以使用动态表来实现这一点,但我刚刚发现我可以使用模板来实现这一点,我对这种语法用法进行了如下培训: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
#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,我曾考虑过使用枚举,但为了使示例更简单,我一直使用布尔值。无论如何,感谢您的提示!您的 包装器
needsfmethod1()
inholdded.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; }