标签: c++-concepts

C++概念是存在类型的一种形式吗?

我在维基百科(Existential_types)上看到存在类型的定义,它在某种程度上与C++中的概念(特别是概念精简版)相似.

C++概念是存在类型的一种形式吗?

如果没有,两者之间有什么区别?

c++ existential-type c++-concepts

11
推荐指数
1
解决办法
2061
查看次数

为什么范围的算法与std的迭代器不兼容?

#include <vector>
#include <iostream>
#include <range/v3/all.hpp>

int main()
{
    auto coll = std::vector{ 1, 2, 3 };

    ranges::copy(
        coll,
        ranges::ostream_iterator<int>{  std::cout, ", " }
    ); // ok

    ranges::copy(
        coll, 
        std::ostream_iterator<int>{ std::cout, ", " }
    ); // error 
}
Run Code Online (Sandbox Code Playgroud)

问题显示在上面的代码中.我使用range-v3-0.3.7.

对我来说,通用算法copy不应该关心目标迭代器类型,只要它满足输出迭代器的要求即可.

如果是这样,为什么范围的算法不与std的迭代器兼容?

c++ iterator c++-concepts range-v3 c++20

11
推荐指数
1
解决办法
528
查看次数

C++ 概念:检查是否派生自具有未知模板参数的模板化类

有没有一种方法可以使用 C++ 概念来要求类派生自模板化类,而模板化类的模板参数又是另一个模板化类的派生类。

例子:

template <class T>
class A{};

template <class T>
class B{};

class X{};
class Y : public A<X> {};

class Z : public B<Y> {};
Run Code Online (Sandbox Code Playgroud)

我如何办理登机手续B,这是某些人的T表格而不指定是什么?我不想添加到 的模板参数列表中,因为我不想在派生自的每个实例上更改代码(例如最后一行)。std::is_base_of<A<X>,T>XXXBBclass Z

c++ c++-concepts c++20

11
推荐指数
1
解决办法
2203
查看次数

当我们已经有类和接口时,为什么构思概念(通用编程)?

也在programmers.stackexchange.com上:

我知道STL概念必须存在,并且将它们称为"类"或"接口"是愚蠢的,而实际上它们只是文档化(人类)概念,当时无法转换为C++代码,但是当有机会扩展语言来容纳概念时,他们为什么不简单地修改类和/或引入接口的功能?

是不是一个非常类似于接口的概念(100%抽象类没有数据)?通过观察它,在我看来接口只是缺乏对公理的支持,但也许公理可以引入C++的接口(考虑假设采用C++中的接口来接管概念),不是吗?我认为甚至可以轻松地将自动概念添加到这样的C++接口(自动界面LessThanComparable,任何人?).

Concept_map 与Adapter模式非常相似吗?如果所有方法都是内联的,那么适配器在编译时间之外基本上不存在; 编译器只是用内联版本替换对接口的调用,在运行时直接调用目标对象.

我听说过一种称为静态面向对象编程的东西,它实质上意味着在泛型编程中有效地重用面向对象的概念,从而允许使用大多数OOP的功能而不会产生执行开销.为什么不进一步考虑这个想法?

我希望这很清楚.如果你认为我不是,我可以改写这个; 请告诉我

c++ oop generic-programming c++-concepts

10
推荐指数
1
解决办法
435
查看次数

C++概念占位符类型推导

在范围符合规范N4622Same概念被定义为采取两种类型TU,但有时用作内requires只有一个这样的:

{ t } -> Same<T>;
Run Code Online (Sandbox Code Playgroud)

能够扣除第二种类型的规则是什么U?(例如来自Concepts spec N4630)

最简单的类似例子是:

template <class T, class U>
concept bool C = (sizeof(T) == sizeof(U)) && (sizeof(U) != 1);

template <class T>
concept bool D = requires(T t){
  // How is U deduced here? 
  {t} -> C<T>; 
};

template <class T>
  requires D<T>
void fn() {}

int main() {
  // Fails with: unable to deduce placeholder type 'C<char>' from 't' …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts

10
推荐指数
1
解决办法
1062
查看次数

为什么CopyConstructible类型也必须是MoveConstructible?

cppreference中所述,类型TCopyConstructible的要求是它也是MoveConstructible.

STL CopyConstructible概念的草案包含:

template <class T>
concept CopyConstructible =
   std::MoveConstructible<T> &&
   std::Constructible<T, T&> && std::ConvertibleTo<T&, T> &&
   std::Constructible<T, const T&> && std::ConvertibleTo<const T&, T> &&
   std::Constructible<T, const T> && std::ConvertibleTo<const T, T>;
Run Code Online (Sandbox Code Playgroud)

它支持命名的需求声明.鉴于上述定义,类似于:

struct HaveCopy {
   HaveCopy(const HaveCopy&)  = default;
   HaveCopy(HaveCopy&&)       = delete;
   HaveCopy& operator= (const HaveCopy&)  = default;
   HaveCopy& operator= (HaveCopy&&)       = delete;
};
Run Code Online (Sandbox Code Playgroud)

没有简单的测试:

static_assert(std::CopyConstructible<HaveCopy>);
Run Code Online (Sandbox Code Playgroud)

而它通过了旧的:

static_assert(std::is_copy_constructible<HaveCopy>::value);
Run Code Online (Sandbox Code Playgroud)

那么,问题是为什么呢?标准委员会对此事的意图是什么?HaveCopy不是可构造的,但在我看来几乎是可复制的,并且std::is_copy_constructible<>与我一致.

Copyable概念也继承了相同的行为,即:

template <class T>
concept Copyable …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20

10
推荐指数
1
解决办法
274
查看次数

是否允许require表达式“捕获”封闭范围的变量?

在下面的示例中,函数自变量用于测试require表达式是否充分利用了它们。require表达式不带参数;它直接使用函数作用域中的变量:

#include <cstddef>
#include <vector>

template<typename T>
void Resize(T &v, std::size_t const n)
{
  if constexpr (requires { v.resize(n); })
    v.resize(n);
}

template<typename T>
void Eziser(T &v, std::size_t const n)
{
  if constexpr (requires { v.eziser(n); })
    v.eziser(n);
}

int main()
{
  std::vector<int> v;

  Resize(v, 10u);
  Eziser(v, 10u);
}
Run Code Online (Sandbox Code Playgroud)

上面的代码使用Clang概念分支进行编译。但是,GCC10仅接受对的呼叫Resize。GCC9 ICE。Clang正确接受吗?

c++ c++-concepts c++20

10
推荐指数
1
解决办法
143
查看次数

非类型模板参数和需要

我正在学习概念,我想不出一种方法来限制非类型模板参数的值(不是类型)。

编译的代码示例,尽管我希望它没有(由于需求失败):

#include <cassert>

enum Bla{
    Lol, 
    Haha
};

template<Bla b>
requires requires{
    // my guess is that this just checks that this is valid expression, not
    // that it is true
    b>1; 
}
void f(){
    assert(b>1);
}

int main() {
    f<Lol>(); // compiles, not funny ;)
}
Run Code Online (Sandbox Code Playgroud)

注意:这是一个简化的例子(我想要“模板重载”)所以static_assert对我不利,我试图避免,std::enable_if因为语法是可怕的。

c++ c++-concepts c++20 non-type-template-parameter

10
推荐指数
2
解决办法
372
查看次数

概念可能会取代 C++ 中的类型特征吗?

我已经知道这个概念是一个编译时谓词,它可以约束模板或auto.

我发现这些概念将返回 type 的纯右值bool,所以我可以打印它来测试自己。

我还阅读了这个特定问题Can概念(C++ 20)可以用作布尔值吗?以及澄清可用作布尔值的概念的答案。

[temp.names] (8) 一个concept-id 是一个simple-template-id,其中template-name 是一个concept-name。概念 ID 是 bool 类型的纯右值,并且不命名模板特化。如果指定的模板参数满足概念的规范化约束表达式 ([temp.constr.constr]),则概念 ID 评估为真,否则为假。

例如:

template <typename T>
concept meowable = requires (T obj) {
    { obj.meow() } -> std::same_as<T&>;
};

struct Dog {};
struct Cat { Cat& meow(); };
struct Wolf { Wolf& woof(); };
Run Code Online (Sandbox Code Playgroud)

应用:

std::cout << std::boolalpha;

std::cout << "Has meow?" << '\n'
          << "Dog:  " << meowable<Dog>  << '\n'
          << "Cat:  " << meowable<Cat>  << '\n' …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits template-meta-programming c++-concepts c++20

10
推荐指数
1
解决办法
284
查看次数

使用 require 子句仅有条件地存在成员变量

member我希望使内部的存在dat依赖于B(或其他一些概念)。

template <bool B>
struct dat {
    void member_func() requires (B) {} //ok
    std::byte member requires (B); //err
};
Run Code Online (Sandbox Code Playgroud)

我知道这可能与专业化有关,但据我所知,如果需要多个不同的成员要求,那会变得非常难看。

如果没有专门化,这种行为是否可能?

c++ templates c++-concepts c++20

10
推荐指数
1
解决办法
1168
查看次数