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 - Fatal编程技术网

C++ 我有一堆模板参数,我想对我的用户隐藏。我该怎么做?

C++ 我有一堆模板参数,我想对我的用户隐藏。我该怎么做?,c++,templates,C++,Templates,我有一个超类,它是根据它使用的几个内部类型定义的。子类化按如下方式执行: template <class InternalType1, class InternalType2> class Super { ... } class Sub : Super <interalTypeClass1, interalTypeClass2> { ... } 模板 超级班 { ... } 组别:超级 { ... } 但是,当我想编写一个函数,该函数使用指向超

我有一个超类,它是根据它使用的几个内部类型定义的。子类化按如下方式执行:

template <class InternalType1, class InternalType2>
class Super 
{
    ...
}

class Sub : Super <interalTypeClass1, interalTypeClass2>
{ 
    ...
}
模板
超级班
{
...
}
组别:超级
{ 
...
}
但是,当我想编写一个函数,该函数使用指向超类的指针时,会发生以下情况:

template <class InternalType1, class InternalType2>
void function(Super<InternalType1, InternalType2>* in) { ... }
模板
空函数(Super*in){…}
用户真的不应该知道关于内部类的任何信息,而应该只关心函数的使用。有些模板列表变得非常大,在我看来,期望用户每次都通过它们是浪费

有什么建议吗

编辑:该函数需要知道正在使用的内部类型,因此,除非有办法在编译时访问模板类型,否则我认为没有解决方案

潜在解决方案:让每个班级做以下工作:

#define SubTemplateArgs <SubTypeName, SubInternalType1, SubInternalType2>
#定义子模板参数

将以下typedef添加到子类:

typedef Super<internalTypeClass1,internalTypeClass2> MySuper;

typedefs的问题是编译器在错误消息中使用完整的类名。也许像这样的方法会更好:

class MySuper : public Super<internal1, internal2> {
    // forward constructors
}
class MySuper:public Super{
//正向构造函数
}

您可以更改
Super
界面

template <class Types>
class Super {
    ...
};

class SubTypes {
  typedef interalTypeClass1 InternalType1;
  typedef interalTypeClass2 InternalType2;
};

class Sub : public Super <SubTypes> { 
    ...
};
以及
操作符
模板
超级班{
私人:
/*...*/
公众:
类型DEF TInternal1内部类型1;
typedef TInternal2内部类型2;
/*...*/
};
typedef Super IntCharSuper;
typedef超级BoolCharSuper;
类Sub1:IntCharSuper{/*…*/};
Sub2类:IntCharSuper{/*…*/};
Sub3类:BoolCharSuper{/*…*/};
/***
*functionA(下面)只能获取指向
*从IntCharSuper继承的类
**/
无效函数(IntCharSuper*in){
INTCHARSPER::内部\u类型\u 1内部1\u变量;
INTCHARSPER::内部_类型_2内部2_变量;
//我们现在有两个内部类型的变量。。。
}
/***
*functionB(如下)可以获取一个指向从任何类型的超类继承的类的对象的指针,
*无论那个超级的模板参数是什么。
*因此函数B将适用于从继承的类型
*IntCharSuper、BoolCharSuper、Super或Tinterna1和Tinterna2的任何其他内容。
**/
模板
无效功能B(TSuper*in){
typename TSuper::internal\u type\u 1 internal1\u变量;/*此处需要typename*/
typename TSuper::internal\u type\u 2 internal2\u变量;/*此处需要typename*/
//我们现在有两个内部类型的变量。。。
}
int main(int argc,const char*argv){
亚基1 s1;
Sub2-s2;
Sub3-s3;
function(&s1);//好的,s1继承IntCharSuper
function(&s2);//好的,s2继承IntCharSuper
functionA(&s3);//错误,s3未将IntCharSuper作为父级
functionB(&s2);//好的,s2继承自定义内部类型1和内部类型2的类
functionB(&s3);//好的,s3继承自一个定义内部类型1和内部类型2的类
返回0;
}
用户真的不应该知道关于内部类的任何信息,而应该只关心函数的使用

问题在于,模板选项的每个不同组合都定义了不同的类

你不能这样做

vector<Super<int,int>> a;
a.push_back( Super<float,float>() );
向量a;
a、 向后推(Super());
类似地,您不想编写的函数也有相同的问题,您有多个函数重载

您可以选择使用typedef来命名各种组合(正如已经建议的),或者您也可以使用Super所基于的一些更常见的父类

class SuperDoooper {
  virtual SomeMethod();
}
template <class InternalType1, class InternalType2>
class Super 
{
    SomeMethod() { InternalType1.. }
}

class Sub : Super <interalTypeClass1, interalTypeClass2>
{ 
    ...
}


function( SupoerDoooper *in ) { in->SomeMethod(); }
类超级操作器{
虚拟方法();
}
模板
超级班
{
SomeMethod(){InternalType1..}
}
组别:超级
{ 
...
}
函数(supoerdooper*in){in->SomeMethod();}

+1不幸的是,typedef不适用于部分专门化:(我会将其添加为一个免费的typedef,而不是一个成员typedef,因为OP将有多个子类型,然后存在
Sub1::MySuper,Sub2::MySuper
…没有人会知道它们是否相同…因此,与其使用免费的typedef,不如使用一个免费的typedef…然后您还可以将子类编写为class Sub:MySuper{/*/});问题是函数需要知道内部类型。有什么方法可以传递它们吗?@Alex:将公共类型定义添加到Super:
typedef InternalType1 internal1_type;
typedef InternalType2 internal2_type;
,然后您可以使用
Super::internal1_type
在函数中访问这些类型>我想我遗漏了一些东西。这难道不会让
函数
只接受
超级*
?但提问者似乎也希望接受
超级*
。不要使用typedefs…这是创建typedefs的一种情况。不要为此使用宏。我会用最好的方式添加一个额外的答案(IMHO)这样做。事实上,没有定义。使用typedefs。那么我该如何使用typedefs呢?只需将内部对象包装在公共typedef中并将其传递给函数?这是一个很好的观点。我认为这是我从现在开始要做的事情,因为标准库这样做会激怒我。这是编译器的问题,而不是语言的问题事实上,从语言的角度来看,typedef是最好的解决方案,但你是对的,有时完整的类名可能会令人恼火,但在其他情况下,如果你没有(或直到你有…)关于typedef的真正类型的所有信息,你将无法快速调试编译错误。
std::basic_string< T, std::char_traits<T>, std::allocator<T> >
template <class TInternal1, TInternal2>
class Super {
    private:
        /*...*/
    public:
        typedef TInternal1 internal_type_1;
        typedef TInternal2 internal_type_2;
        /*...*/
};

typedef Super<int, char>    IntCharSuper;
typedef Super<bool, char>   BoolCharSuper;

class Sub1 : IntCharSuper {/*...*/};
class Sub2 : IntCharSuper {/*...*/};
class Sub3 : BoolCharSuper {/*...*/};


/***
 * functionA (below) can only take a pointer to an object of a
 * class which inherits from IntCharSuper
 **/
void functionA(IntCharSuper* in){
    IntCharSuper::internal_type_1 internal1_variable;
    IntCharSuper::internal_type_2 internal2_variable;
    // we now have 2 variables of the internal types...
}

/***
 * functionB (below) can take a pointer to an object of a class which inherits from any kind of Super, 
 * no matter what the template parameters of that Super are.
 * so functionB will work for types which inherit from 
 *    IntCharSuper, BoolCharSuper, Super<YourCustomType, void*>, or anything else for TInternal1 and TInternal2.
 **/
template <class TSuper>
void functionB(TSuper* in) {
    typename TSuper::internal_type_1 internal1_variable; /* typename is needed here */
    typename TSuper::internal_type_2 internal2_variable; /* typename is needed here */
    // we now have 2 variables of the internal types...
}

int main(int argc, const char* argv) {
        Sub1 s1;
        Sub2 s2;
        Sub3 s3;
        functionA(&s1);  //OK, s1 inherits IntCharSuper
        functionA(&s2);  //OK, s2 inherits IntCharSuper
        functionA(&s3);  //ERROR, s3 hasnt got IntCharSuper as parent

        functionB(&s2); //OK, s2 inherits from a class which defines internal_type_1 and internal_type_2
        functionB(&s3); //OK, s3 inherits from a class which defines internal_type_1 and internal_type_2

        return 0;
}
vector<Super<int,int>> a;
a.push_back( Super<float,float>() );
class SuperDoooper {
  virtual SomeMethod();
}
template <class InternalType1, class InternalType2>
class Super 
{
    SomeMethod() { InternalType1.. }
}

class Sub : Super <interalTypeClass1, interalTypeClass2>
{ 
    ...
}


function( SupoerDoooper *in ) { in->SomeMethod(); }