C++;概念与静态断言 什么是C++概念中的新概念?据我所知,它们在功能上等同于使用static\u assert,但以一种“好”的方式,这意味着编译器错误将更具可读性(正如Bjarne Stroustup所说,您不会得到10页或错误,而只会得到一页)

C++;概念与静态断言 什么是C++概念中的新概念?据我所知,它们在功能上等同于使用static\u assert,但以一种“好”的方式,这意味着编译器错误将更具可读性(正如Bjarne Stroustup所说,您不会得到10页或错误,而只会得到一页),c++,static-assert,c++-concepts,C++,Static Assert,C++ Concepts,基本上,使用概念所能做的一切都可以通过使用static\u assert实现,这是真的吗 有什么我遗漏的吗?tl;博士 与静态断言相比,概念更强大,因为: 它们为您提供了良好的诊断,这是使用静态断言不容易实现的 它们允许您轻松地重载模板函数,而无需std::enable_if(只有static_断言,这是不可能的) 它们允许您定义静态接口,并在不丢失诊断的情况下重用它们(在每个函数中需要多个static\u断言) 它们可以让您更好地表达您的意图并提高可读性(这是模板的一个大问题) 这可以缓解

基本上,使用概念所能做的一切都可以通过使用
static\u assert
实现,这是真的吗

有什么我遗漏的吗?

tl;博士 与静态断言相比,概念更强大,因为:

  • 它们为您提供了良好的诊断,这是使用
    静态断言不容易实现的
  • 它们允许您轻松地重载模板函数,而无需
    std::enable_if
    (只有
    static_断言
    ,这是不可能的)
  • 它们允许您定义静态接口,并在不丢失诊断的情况下重用它们(在每个函数中需要多个
    static\u断言
  • 它们可以让您更好地表达您的意图并提高可读性(这是模板的一个大问题)
这可以缓解以下情况:

  • 模板
  • 静态多态性
  • 超载
并成为有趣范例的基石


什么是概念?

概念表示“类”(不是在C++项中,而是作为满足某个要求的类型的“组”)。例如,您可以看到,该概念表达了以下类型集:

  • 允许调用
    std::swap
您可以很容易地看到,例如,
std::string
std::vector
std::deque
int
等等。。。满足此要求,因此可在以下功能中互换使用:

template<typename Swappable>
void func(const Swappable& a, const Swappable& b) {
    std::swap(a, b);
}
否则,您将失去区分哪些需求未得到满足的能力

相反,对于概念,您只需定义概念并通过编写以下内容加以实施:

template<Container C>
void func_a(...);

template<Container C>
void func_b(...);
没有概念的替代方案是:

template<typename T>
std::enable_if<
    Container<T>::value,
    int
> func(T& c);

template<typename T>
std::enable_if<
    SequenceContainer<T>::value,
    int
> func(T& c);
然后,假设您拥有派生对象的多态
std::vector
,您可以执行以下操作:

for (auto& o : objects) { 
    o.update();
    o.draw();
}
很好,但除非您想使用多继承或基于实体组件的系统,否则每个类只能使用一个可能的接口

但是,如果您确实想要静态多态性(多态性毕竟不是动态的),您可以定义一个
对象
概念,它需要
更新
绘制
成员函数(可能还有其他函数)

此时,您可以创建一个自由函数:

template<Object O>
void process(O& o) {
    o.update();
    o.draw();
}
模板
无效流程(O&O){
o、 更新();
o、 draw();
}
之后,您可以为您的游戏对象定义另一个具有其他要求的界面。这种方法的美妙之处在于,您可以开发任意多的接口,而无需任何其他工具

  • 修改您的类
  • 需要一个基类
它们都是在编译时检查和执行的

这只是一个愚蠢的例子(非常简单),但是概念确实为C++中的模板打开了一个全新的世界。


如果你想要更多的信息,你可以在C++概念上和Haskell类型类。

关于它有一篇维基百科文章:这个建议不支持最新的标准定义AAFIR。那么,你的问题是关于什么的?(你不能使用概念提案中的任何内容!)@Flovdis:Wikipedia的文章没有将其与static_assert@πάντα进行对比ῥεῖ: 概念如何比简单使用静态断言更好?我想他们(更好)了,但似乎找不到地方。@πάνταῥεῖ, 据我所知,它被改为仅仅是约束,因为概念没有及时准备好,概念仍在全力尝试进入下一次更新。谢谢你的回答,但我不确定重复可用性是否比静态可用性更好,正如你用容器解释的那样。您可以有一个谓词,例如Container,它会告诉您类C是否满足作为容器的要求。然后,您需要做的一切都是静态的。对吗?@谢谢,我会在下一次修订中澄清的。这是一个糟糕的答案。5年后我在这里读到:)再次感谢你!此外,C++概念可以用作编译时常量值。(顺便说一句,Concept::value是错误的,您只需要Concept)。例如:
static\u断言(std::same\u-as)
template<typename T>
std::enable_if<
    Container<T>::value,
    int
> func(T& c);

template<typename T>
std::enable_if<
    SequenceContainer<T>::value,
    int
> func(T& c);
static_assert(Concept<T>::value);
struct Object {
    // …
    virtual update() = 0;
    virtual draw() = 0;
    virtual ~Object();
};
for (auto& o : objects) { 
    o.update();
    o.draw();
}
template<Object O>
void process(O& o) {
    o.update();
    o.draw();
}