C++ 从模板类的另一个实例创建模板类的实例时忽略模板参数
我想在创建类的实例C++ 从模板类的另一个实例创建模板类的实例时忽略模板参数,c++,templates,c++14,decltype,C++,Templates,C++14,Decltype,我想在创建类的实例DeriveGenerator时省略一些模板参数T1,T2,以改善我的生活 下面是我所遇到的情况的最终简化版本 我的库:- class B1{};class B2{}; class B3:public B1{}; class B4:public B2{}; int main() { //v this is what I have to BaseGenerator<B1,B2> baseGen; DeriveGenerator<B3,B4
DeriveGenerator
时省略一些模板参数T1,T2
,以改善我的生活
下面是我所遇到的情况的最终简化版本
我的库:-
class B1{};class B2{};
class B3:public B1{};
class B4:public B2{};
int main() {
//v this is what I have to
BaseGenerator<B1,B2> baseGen;
DeriveGenerator<B3,B4,B1,B2> deriveGen; //so dirty #1
deriveGen.base=&baseGen;
deriveGen.generateDerive();
}
重要的部分是类声明。(此行
)它们的内部内容只是一种填充
template<class T1,class T2>class BaseGenerator{ //<-- this line
public: std::pair<T1*,T2*> generateBase(){
/** actually create T3,T4 internally */
return std::pair<T1*,T2*>(nullptr,nullptr);
}
};
template<class T3,class T4,class T1,class T2>class DeriveGenerator{ //<-- this line
public: Base<T1,T2>* base;
public: std::pair<T3*,T4*> generateDerive(){
auto pp=base->generateBase();
return std::pair<T3*,T4*>((T3*)(pp.first),(T4*)(pp.second));
}
};
或者至少类似于:-
BaseGenerator<B1,B2> baseGen;
DeriveGenerator<B3,B4, DECLARATION_TYPE(baseGen) > deriveGen; //<-- modified
deriveGen.base=&baseGen;
因此,在声明deriveGen
时,我无法访问baseGen
的真实实例这是最难的部分 不过,我可以通过
decltype
引用baseGen
的类型。(很抱歉没有提及此事)不确定您想要什么,但。。。我想您可以这样定义
DeriveGenerator
template <typename, typename, typename>
class DeriveGenerator;
template <typename T3, typename T4, typename T1, typename T2>
class DeriveGenerator<T3, T4, BaseGenerator<T1, T2>>
{
public:
BaseGenerator<T1,T2>* base;
public:
std::pair<T3*,T4*> generateDerive ()
{
auto pp=base->generateBase();
return std::pair<T3*,T4*>((T3*)(pp.first),(T4*)(pp.second));
}
};
如果可以将DerivegGenerator定义更改为:
template<class T3, class T4, class BaseT>
class DeriveGenerator{
public:
BaseT* base = nullptr;
std::pair<T3*, T4*> generateDerive(){
auto pp = base->generateBase();
return {(T3*)(pp.first), (T4*)(pp.second)};
}
};
模板
类派生生成器{
公众:
BaseT*base=nullptr;
std::pair GenerateDrive(){
自动pp=base->generateBase();
返回{(T3*)(第一页),(T4*)(第二页)};
}
};
您可以使用:
BaseGenerator<B1, B2> baseGen;
DeriveGenerator<B3, B4, decltype(baseGen)> deriveGen;
baseGen;
DeriveGenerator deriveGen;
否则,我建议创建一个助手:
template <typename B3, typename B4, typename B1, typename B2>
DeriveGenerator<B3, B4, B1, B2>
MakeDerived(BaseGenerator<B1, B2>& baseGen)
{
DeriveGenerator<B3, B4, B1, B2> deriveGen;
deriveGen.base = &baseGen;
return deriveGen;
}
模板
衍生发电机
MakeDerived(BaseGenerator和baseGen)
{
DeriveGenerator deriveGen;
deriveGen.base=&baseGen;
回归素食主义;
}
然后使用
BaseGenerator<B1,B2> baseGen;
auto deriveGen = MakeDerived<B3, B4>(baseGen);
baseGen;
auto-deriveGen=MakeDerived(baseGen);
我认为将DeriveGenerator
的T1
和T2
模板参数推入实际的generatedrive
方法本身更简单:
template<class T3,class T4>
class DeriveGenerator{
public:
template<class T1, class T2, template<class, class> class Base>
std::pair<T3*,T4*> generateDerive(Base<T1, T2>* base){
static_assert(std::is_base_of<T1, T3>::value && std::is_base_of<T2, T4>::value, "T1 should be base of T3 and T2 should be base of T4");
auto pp=base->generateBase();
return std::pair<T3*,T4*>((T3*)(pp.first),(T4*)(pp.second));
}
};
@我知道你的思想食物是如此美味!它的有用性不仅仅是评论级别。谢谢。什么是行
模板类DerivegGenerator代码>呼叫?远期申报?我从来不知道我不需要完全定义基本情况。我只是特别提到这一点,而且它似乎是可编译的。@javaLover-如果我没有错的话(但考虑到我在术语方面很差),它是一个类“declatarion”;下面的模板类DeriveGenerator{/*…*/}
是类的部分专门化的“定义”。如果专门化涵盖了所有用例,那么您不需要类的泛型版本的定义。哇,对我来说是新知识。谢谢。不幸的是,在我的例子中,我无法在声明deriveGen
时获得baseGen
的实例,我还想直接参考B1
和B2
。谢谢。您可以使用B1\u type=B1添加在BaseGenerator
中使用code>,因此以后可以使用BaseT::B1_type
(如std::vector::value_type
)。否则仍然存在如max66所示的部分专门化。此解决方案非常有用。很遗憾,我只能接受一种解决方案,对不起。我不想每次都传递&baseGen
,所以我必须缓存它们。但是谢谢!从另一个角度看待这个问题是很好的。
BaseGenerator<B1, B2> baseGen;
DeriveGenerator<B3, B4, decltype(baseGen)> deriveGen;
template <typename B3, typename B4, typename B1, typename B2>
DeriveGenerator<B3, B4, B1, B2>
MakeDerived(BaseGenerator<B1, B2>& baseGen)
{
DeriveGenerator<B3, B4, B1, B2> deriveGen;
deriveGen.base = &baseGen;
return deriveGen;
}
BaseGenerator<B1,B2> baseGen;
auto deriveGen = MakeDerived<B3, B4>(baseGen);
template<class T3,class T4>
class DeriveGenerator{
public:
template<class T1, class T2, template<class, class> class Base>
std::pair<T3*,T4*> generateDerive(Base<T1, T2>* base){
static_assert(std::is_base_of<T1, T3>::value && std::is_base_of<T2, T4>::value, "T1 should be base of T3 and T2 should be base of T4");
auto pp=base->generateBase();
return std::pair<T3*,T4*>((T3*)(pp.first),(T4*)(pp.second));
}
};
BaseGenerator<B1,B2> baseGen;
DeriveGenerator<B3,B4> deriveGen;
deriveGen.generateDerive(&baseGen);
class B5{}; // new class B5 nobody inherits from
BaseGenerator<B1, B5> bad_baseGen;
deriveGen.generateDerive(&bad_baseGen);