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++;概念检查与继承 P>使用虚拟函数和C++继承机制与使用模板和类似Boost概念之类的关系是什么?_C++_Templates_Polymorphism - Fatal编程技术网

C++;概念检查与继承 P>使用虚拟函数和C++继承机制与使用模板和类似Boost概念之类的关系是什么?

C++;概念检查与继承 P>使用虚拟函数和C++继承机制与使用模板和类似Boost概念之类的关系是什么?,c++,templates,polymorphism,C++,Templates,Polymorphism,似乎有相当多的重叠是可能的。也就是说,这两种方法都有可能实现多态行为。那么,什么时候偏袒一方比偏袒另一方更有意义呢 我之所以提出这个问题,是因为我有一个模板化的容器,其中容器本身具有层次关系。我想编写使用这些容器的算法,而不关心它是哪个特定的容器。此外,知道模板类型满足某些概念(例如,可比较),一些算法也会受益 因此,一方面,我希望容器的行为具有多态性。另一方面,如果我想正确实现一些算法,我仍然需要使用概念。初级开发人员应该做什么?如果可以在编译时做出决定,请使用模板。否则,请使用继承和虚拟函数

似乎有相当多的重叠是可能的。也就是说,这两种方法都有可能实现多态行为。那么,什么时候偏袒一方比偏袒另一方更有意义呢

我之所以提出这个问题,是因为我有一个模板化的容器,其中容器本身具有层次关系。我想编写使用这些容器的算法,而不关心它是哪个特定的容器。此外,知道模板类型满足某些概念(例如,可比较),一些算法也会受益


因此,一方面,我希望容器的行为具有多态性。另一方面,如果我想正确实现一些算法,我仍然需要使用概念。初级开发人员应该做什么?

如果可以在编译时做出决定,请使用模板。否则,请使用继承和虚拟函数。

是的,多态行为在这两种机制中都是可能的。事实上,两者也被称为多态性

虚拟函数提供动态多态性(因为它是在运行时决定的),而模板提供静态多态性(一切都是在编译时决定的)

这应该也回答了选择哪一个的问题。只要可能,最好将工作转移到编译时。因此,当您可以摆脱它时,使用模板来解决您的多态性需求。当这不可能时(因为需要使用运行时类型信息,因为编译时不知道确切的类型),可以使用动态多态性


(当然,选择其中一种可能还有其他原因。特别是,模板要求您将大量代码移动到头文件中,这可能是一个问题,也可能不是一个问题,编译速度往往会受到影响。)

在这种特定情况下,您可以执行以下操作

template<typename T>
class ContainerBase{};

template<typename T>
class ContainerDerived : public ContainerBase<T> {};
模板
类容器基{};
模板
集装箱运输类:公共集装箱库{};

由于每个“容器”类型对于每个模板类型都是唯一的,因此每个容器类型的成员函数没有理由不能针对模板类型的特性进行专门化

我认为概念是一种元接口。他们根据能力对类型进行分类。下一个C++版本提供本地概念。直到我遇到C++1x的概念,以及它们如何允许将不同但不相关的类型组合在一起,我才理解它。假设您有一个
范围
界面。你可以用两种方法来建模。一种是子类型关系:

当然,从中派生的每个类都实现了Range接口,并且可以与函数一起使用。但现在你看到它是有限的。数组呢?这也是一个范围

T t[N];

begin() => t
end() => t + size()
size() => N
遗憾的是,您无法从实现该接口的Range类派生数组。您需要一个额外的方法(重载)。第三方容器呢?库的用户可能希望将其容器与函数一起使用。但是他不能改变他们容器的定义。在这里,概念进入游戏:

auto concept Range<typename T> {
    typename iterator;
    iterator T::begin();
    iterator T::end();
    size_t T::size();
}
这是一种很好的替代性。任何类型都符合这个概念,而不仅仅是那些积极实现某些接口的类型。下一个C++标准进一步:它定义了一个容器> /Cuff>概念,它将被简单数组(由一些被定义的类型的概念图定义为某种类型适合某些概念)和其他现有的标准容器。p> 我之所以提出这个问题,是因为我有一个模板化的容器,其中容器本身具有层次关系。我想编写使用这些容器的算法,而不关心它是哪个特定的容器。此外,知道模板类型满足某些概念(例如,可比较),一些算法也会受益

实际上,您可以使用模板同时执行这两项操作。您可以保持层次关系以共享代码,然后以通用方式编写算法。例如,传达您的容器具有可比性。这与实现标准随机访问/转发/输出/输入迭代器类别类似:

// tag types for the comparator cagetory
struct not_comparable { };
struct basic_comparable : not_comparable { };

template<typename T>
class MyVector : public BasicContainer<T> {
    typedef basic_comparable comparator_kind;
};

/* Container concept */
T::comparator_kind: comparator category
//比较器的标记类型
结构不可比{};
结构基本可比:不可比{};
模板
MyVector类:公共基本容器{
typedef basic_comparable comparator_kind;
};
/*容器概念*/
T::comparator\u种类:comparator类别
实际上,这是一个合理的简单方法。现在您可以调用一个函数,它将转发到正确的实现

template<typename Container>
void takesAdvantage(Container const& c) {
    takesAdvantageOfCompare(c, typename Container::comparator_kind());
}

// implementation for basic_comparable containers
template<typename Container>
void takesAdvantage(Container const& c, basic_comparable) {
    ...
}

// implementation for not_comparable containers
template<typename Container>
void takesAdvantage(Container const& c, not_comparable) {
    ...
}
模板
空取优势(集装箱建造和控制){
利用比较的优势(c,typename容器::comparator_kind());
}
//基本容器的实现
模板
空位优势(集装箱结构和成本、基本成本){
...
}
//不可比容器的实现
模板
无效利用率(集装箱结构和成本,不可比){
...
}

实际上,可以使用不同的技术来实现这一点。另一种方法是使用
boost::enable_if
每次启用或禁用不同的实现

> P>作为编译时间和运行时多态性之间差异的一个简单例子,请考虑以下代码:

template<typename tType>
struct compileTimePolymorphism
{ };

// compile time polymorphism,
// you can describe a behavior on some object type
// through the template, but you cannot interchange 
// the templates
compileTimePolymorphism<int> l_intTemplate;
compileTimePolymorphism<float> l_floatTemplate;
compileTimePolymorphism *l_templatePointer; // ???? impossible

struct A {};
struct B : public A{};
struct C : public A{};

// runtime polymorphism 
// you can interchange objects of different type
// by treating them like the parent
B l_B;
C l_C:
A *l_A = &l_B;
l_A = &l_C;
模板
结构编译器多态性
{ };
//编译时多态性,
//您可以描述某个对象类型上的行为
//通过模板,但不能交换
//模板
编译模板;
CompileTimel_浮动模板;
CompileTime多态性*l_templatePointer;//????不可能的
结构A{};
结构B:公共A{};
结构C:公共A{};
//运行时多态性
//您可以交换dif的对象
template<typename Container>
void takesAdvantage(Container const& c) {
    takesAdvantageOfCompare(c, typename Container::comparator_kind());
}

// implementation for basic_comparable containers
template<typename Container>
void takesAdvantage(Container const& c, basic_comparable) {
    ...
}

// implementation for not_comparable containers
template<typename Container>
void takesAdvantage(Container const& c, not_comparable) {
    ...
}
template<typename tType>
struct compileTimePolymorphism
{ };

// compile time polymorphism,
// you can describe a behavior on some object type
// through the template, but you cannot interchange 
// the templates
compileTimePolymorphism<int> l_intTemplate;
compileTimePolymorphism<float> l_floatTemplate;
compileTimePolymorphism *l_templatePointer; // ???? impossible

struct A {};
struct B : public A{};
struct C : public A{};

// runtime polymorphism 
// you can interchange objects of different type
// by treating them like the parent
B l_B;
C l_C:
A *l_A = &l_B;
l_A = &l_C;
template<typename tType>
struct myContainer : public tType
{};