标签: c++-concepts

需要 C++20 函数模板中的子句定位

在 C++20 中,您可以通过几种不同的方式编写约束函数模板:

template <typename T>
concept Fooable = true;

template <typename T>
    requires Fooable<T>
void do_something(T&); // (1)

template <typename T>
void do_something(T&) requires Fooable<T>; // (2)
Run Code Online (Sandbox Code Playgroud)

根据这个问题中接受的答案,这两种形式是等价的(这一直是我的理解)。

但是,我注意到 GCC 12.1 认为 (1) 和 (2) 是两个不同的函数,而不是 (2) 是重新声明:可以为两者提供定义,并且尝试调用do_something()是不明确的(示例)。

  • GCC 正确吗?这是两个不同的函数?
  • 如果是这样,两种风格之间在含义上是否存在技术差异?

编辑:

  • 正如评论中指出的,链接的问题指出函数模板声明和定义必须使用相同的“需要样式”。这个限制的原因是什么?

(我依稀记得在 Concepts TS 时代,需求经过“规范化”来决定它们何时等效——我想在 C++20 中不再是这种情况了?)

c++ language-lawyer c++-concepts c++20

4
推荐指数
1
解决办法
1165
查看次数

当参数是智能指针时的概念 std::衍生_from

我有一些像这样的功能

bool RegisterModel (std::shared_ptr<DerivedA> model) { }

bool RegisterModel (std::shared_ptr<DerivedB> model) { }
Run Code Online (Sandbox Code Playgroud)

我想利用 c++ 20 概念并像这样实现它:

bool RegisterModel (std::derived_from<BaseClass> auto model) { }
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为我正在传递共享指针。以某种方式可能需要一个共享指针来保存从BaseClass?派生的对象。

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

4
推荐指数
1
解决办法
1463
查看次数

理解c++20中的convertible_to概念

我对 C++20 概念仍然很陌生,我想知道为什么这不起作用。我想创建一个将数字连接为字符串的函数模板。所以我想尝试一些概念。我曾经std::convertible_to检查输入的数据类型(int在本例中)是否可以转换为std::string. 但我面临着一个我不明白的错误。

//building the concept
template <typename T>
concept ConvertibleToStdString = std::convertible_to<T,std::string>;

//using the concept
template <ConvertibleToStdString T>
std::string concatenate(T a, T b){
    return std::to_string(a) + std::to_string(b);
}

int main(){

    int x{623};
    int y{73};

    auto result = concatenate(x,y);
    std::cout << result << std::endl;
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:

main.cpp:21:34: error: use of function 'std::string concatenate(T, T) [with T = int; std::string = std::basic_string<char>]' with unsatisfied constraints
   21 |     auto result = concatenate(x,y);
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么 …

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

4
推荐指数
1
解决办法
1094
查看次数

如何根据数组的大小启用/禁用函数?

我对 TMP 还很陌生,所以如果这是一个措辞不好的问题,请原谅我。

我正在尝试创建一个非常通用的数学 Vector 类来存储任意数量的组件,但默认为 3 并使用 float 作为其基本表示形式。因此,如果您默认构造这些向量之一,它将保存(0.0f,0.0f,0.0f)

这些值本身存储在 a 中std::array,我想创建访问器函数以方便使用。我目前有这个:

std::array<Type,SIZE> e;
Type x() const {return e.at(0);};
Type y() const {return e.at(1);};
Type z() const {return e.at(2);};
Run Code Online (Sandbox Code Playgroud)

我现在想做的是为第四个组件设置一个,w但只有当该数组的大小 >= 4 时才启用它。所以像这样:

template<class Type, std::enable_if<.......>>
Type w() const {return e.at(3);};
Run Code Online (Sandbox Code Playgroud)

这只是我认为它应该是什么样子的一个模糊的想法。我知道concept存在,但我也在努力为这种情况写一个。

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

4
推荐指数
2
解决办法
182
查看次数

为什么 string_view 和 span 构造函数不使用 C++20 概念?

C++20 和 C++23 引入了迭代器对和范围的模板构造函数std::string_viewstd::span有类似的构造函数。

template<class It, class End>
constexpr basic_string_view(It first, End last); // C++20

template<class R>
explicit constexpr basic_string_view(R&& r); // C++23
Run Code Online (Sandbox Code Playgroud)

该文档包含参数的要求。为什么这些要求没有定义为C++20 概念约束?这不会导致更好的错误消息吗?

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

4
推荐指数
1
解决办法
166
查看次数

如何使用概念检查类型中是否存在类型别名

有没有办法要求给定类型在其中定义类型别名?例如,我如何编写一个概念来检查这是否有效,其中该概念检查类型 T 是否具有类型别名Bar

template <typename T>
concept HasBarType = ????;

template <HasBarType T>
void foo() {
    [[maybe_unused]] T::Bar bar;
}
Run Code Online (Sandbox Code Playgroud)

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

4
推荐指数
1
解决办法
121
查看次数

Scala特性与C++概念之间的区别

Scala traits Haskell类型类和C++ 0x Concepts之间有什么区别?

就像下面这个例子中Observer声明一个抽象成员一样,receiveUpdate Observer实际上是一个"匿名"类型或结构类型.

package observer
trait Subject {
   type Observer = { def receiveUpdate(subject: Any) }
   private var observers = List[Observer]()
   def addObserver(observer:Observer) = observers ::= observer
   def notifyObservers = observers foreach (_.receiveUpdate(this))
}
Run Code Online (Sandbox Code Playgroud)

scala traits typeclass c++11 c++-concepts

3
推荐指数
1
解决办法
1122
查看次数

为什么在C++ Concepts TS中有变量和函数概念?

我一直在研究在GCC 6中实现的C++ 1z N4377概念TS草案,我不明白有两种不同概念的目的:变量概念和函数概念.

功能概念草案的相关部分是[dcl.spec.concept(5.4)]

  • 声明应具有相当于一个功能体{ return E; },其中E是一个约束表达式(14.10.1.3).

对于可变概念,在下一段[(6.3)]中:

  • 初始化器应该是约束表达式.

他们中有什么能做的,对方不能吗?如果没有,是否有理由将两者都包括在内?

注意:最新草案P0121R0在这方面没有任何改变

c++ c++-concepts c++-ts

3
推荐指数
1
解决办法
187
查看次数

写作概念的惯用方法,即该类型是std :: vector

我有以下代码实现以下类型特征:

  • 那种类型 std::vector
  • 这种类型是std::vector整数

它有效,但它非常冗长.
是否有更短/更好的方式来使用概念写这个?
我知道我可以从range-v3或其他类似的库中窃取概念,但我们假设我想自己实现它.

#include <iostream>
#include <string>
#include <type_traits>
#include <vector>

template <class T>
struct is_vector {
  static constexpr bool value = false;
};
template <class T, class A>
struct is_vector<std::vector<T, A> > {
  static constexpr bool value = true;
};

template <class T>
struct is_vector_of_int {
  static constexpr bool value = false;
};

template <class A>
struct is_vector_of_int<std::vector<int, A> > {
  static constexpr bool value = true;
};

// TODO add _v bool …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits c++-concepts c++20

3
推荐指数
3
解决办法
202
查看次数

基于概念的模板成员函数重载

此代码段中显示了一个示例,该示例说明了在没有概念的情况下如何重载模板类的模板成员函数。

现在粗略尝试使用概念编写类似的东西:

template <typename T>
struct Foo{
    Foo(T elem): elem_(elem) {}
    template <typename U = T>  requires Integral<U>
    int get() {
        return -1;
    }
    template <typename U = T>  requires Bool<U>
    int get() {
        return 0;
    }
    T elem_;
};
Run Code Online (Sandbox Code Playgroud)

有两种方法可以组织这种情况:
1.将声明和定义保持在一起:这可以按预期工作。代码段
2。声明和定义分开:无法编译(代码段

鉴于以上所述,我有两个问题:
1. template <typename T> template <typename U=T> member_fn...由于SFINAE,最初需要该原因。有没有办法用Concepts来避免这种情况来进一步简化代码?
2.如何正确区分声明和定义?

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

3
推荐指数
1
解决办法
108
查看次数