标签: c++-concepts

C++20 concepts as Interfaces

Hey I'm trying to design some Interfaces without any runtime overhead using c++20 concepts.

I came up with the following (simplified) concept

/**
 * @brief This concept defines an OSA Interface
*/
template<typename T, typename Task_T>
concept OSA_Layer_T = requires (T a) {
    {T::getName(a)} -> std::same_as<std::string>; ///< Returns the name of the task (if no name is available return the ID as string)
    {T::getId(a)} ->std::same_as<Task_T>;  ///< returns the (underlying) ID of the task
};
Run Code Online (Sandbox Code Playgroud)

Since every OS has it's own …

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

2
推荐指数
1
解决办法
737
查看次数

约束和概念的定义顺序 c++20

概念或约束的正确位置在哪里?

\n

以下代码编译:

\n
void f(int x) { } \n\ntemplate <typename T>\nconcept Concept =\n    requires (T a)\n    { f(a); };\n\n\ntemplate <typename T>\n    requires Concept<T>\nstruct A\n{ };\n\n\n\nint main(){\n    A<int> a;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

但如果我将函数的位置更改f(int)为:

\n
template <typename T>\nconcept Concept =\n    requires (T a)\n    { f(a); };\n\n\nvoid f(int x) { } // <-- new position\n\ntemplate <typename T>\n    requires Concept<T>\nstruct A\n{ };\n\n\n\nint main(){\n    A<int> a;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这不能在 gcc 11.3.0 中编译。我收到以下错误:

\n
main.cpp:27:10: error: template constraint failure for \xe2\x80\x98template<class T>  requires  Concept<T> struct A\xe2\x80\x99\n …
Run Code Online (Sandbox Code Playgroud)

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

2
推荐指数
1
解决办法
91
查看次数

std::convertible_to 无法识别显式可转换类型

根据convertible_to中的 en.cppreference.com :

概念convertible_to<From, To>指定与std::declval()相同类型和值类别的表达式可以隐式和显式转换为To类型,并且两种转换形式是等效的。

我理解这意味着如果有成员,该convertible_to概念将被识别convertible_to<U, V>为满意。即使运算符是显式的而不是隐式运算符。Uexplicit operator V()

但是我发现msvc中不是这样的。

由于静态断言,以下代码无法编译:

#include <concepts>
#include <iostream>

class ExplictClass
{
public:
    inline explicit operator int() const
    {
        return 5;
    }
};

int main()
{
    static_assert(std::convertible_to<ExplictClass, int>, "Explicit not convertible?"); // Fails here, concept not satisfied.
}
Run Code Online (Sandbox Code Playgroud)

这是我对概念的误解std::convertible_to,代码中的错误,还是 en.cppreference.com 中的错误,或者 msvc v19 的不一致性。

附上使用 x64 msvc v19.latest 的编译器资源管理器的链接,其中包含上述代码

编译器浏览器

编辑:

实际需要convertible_to是生成一个to_string函数模板,该模板可以与声明的可转换类型很好地配合,如下所示:

template<class T>
std::string to_string(T val)
{
    std::ostringstream stream; …
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20 compiler-explorer

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

为什么概念要求没有生效

在以下代码中,它在 -std=c++23 标志下编译。为什么概念要求 In 参数不应被引用触发?

#include <concepts>
#include <type_traits>
#include <functional>

template <typename T>
concept NotRef = requires { !std::is_reference_v<T>; };

template <typename In, typename Out>
    requires NotRef<In> // requires that In should not be reference
class SwitchType
{
    using ConstIn = std::add_const_t<In>;
public:
    SwitchType(const In& in)
        : in_{in}
    { }
    ConstIn & in_;
};

int main()
{
    int a{9};
    // Expected behavior: 'requirement not satifsfied'
    // Actural behavior: compiles under c++ 23

    SwitchType<int&, int> mytype{a};
}
Run Code Online (Sandbox Code Playgroud)

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

2
推荐指数
1
解决办法
97
查看次数

require 表达式的隐式可复制要求

以下代码是否需要 T 的隐式复制构造函数,因为参数是按值传递的?或者它的行为类似于 decltype 并且不涉及真正的构造?

template<typename T>
concept Addable = requires (T a, T b){ a + b; };
Run Code Online (Sandbox Code Playgroud)

c++ c++-concepts c++20 requires-expression

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

Generic way for traversing a C++ std::tuple

My goal is to have a generic way to traverse a std::tuple, and the following code tries to show it:

#include <iostream>
#include <tuple>

template <typename t, size_t t_idx, typename t_tuple>
concept visit_tuple_element_value = requires(t &&p_t, const t_tuple &p_tuple) {
  {
    p_t.template operator()<t_idx>(
        std::declval<std::add_const_t<std::add_lvalue_reference_t<t_tuple>>>())
    } -> std::same_as<bool>;
};

template <typename t_tuple, typename t_function, size_t t_idx = 0>
requires(visit_tuple_element_value<t_function, t_idx, t_tuple>)

    void traverse_tuple_values(t_function p_function, const t_tuple &p_tuple) {
  if constexpr (t_idx < std::tuple_size_v<t_tuple>) {
    if (p_function.template operator()<t_idx>(p_tuple)) {
      traverse_tuple_values<t_tuple, t_function, …
Run Code Online (Sandbox Code Playgroud)

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

2
推荐指数
1
解决办法
112
查看次数

如何在C++代码中要求某些概念?

我如何要求和检查的说法是有一定概念C++

例如,标头中的random_shuffle函数algorithm要求其参数是RandomAccessIterators:

  template<typename _RandomAccessIterator>
    inline void
    random_shuffle(_RandomAccessIterator __first, _RandomAccessIterator __last)
    {
      // concept requirements
      __glibcxx_function_requires(_Mutable_RandomAccessIteratorConcept<
            _RandomAccessIterator>)
      __glibcxx_requires_valid_range(__first, __last);

      if (__first != __last)
        for (_RandomAccessIterator __i = __first + 1; __i != __last; ++__i)
          std::iter_swap(__i, __first + (std::rand() % ((__i - __first) + 1)));
    }
Run Code Online (Sandbox Code Playgroud)

我想我不能__glibcxx_function_requires在我自己的代码中使用这些等等?他们是如何工作的?你在代码中检查这样的东西吗?

c++ generics stl c++-concepts

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

C++模板参数默认函数实现

我有一组用作模板参数的类.它们都符合一些非正式的界面(又名概念)

template <typename T>
int func( T& t ) { return t.a() + t.b() + t.c(); }
Run Code Online (Sandbox Code Playgroud)

在这个例子中,我们说我使用FooBar作为参数实例化模板,因此他们必须实现方法a bc.

struct Foo { int a(); int b(); int c(); };
struct Bar { int a(); int b(); int c(); };
Run Code Online (Sandbox Code Playgroud)

现在,我有很多这样的类,我希望有一个函数的默认实现方式.

例如,我想c返回的区别a()b()默认.所以,我希望,这将是足够的,我定义a()b()c()作为将自动执行int c() { return a()- b();},而无需复制此代码的所有类.

我过去通过多态来实现这个结果(通过在基类中定义a()b()使用默认(虚拟)实现的纯虚函数c()),但出于性能原因,我放弃了这种机制.

我想知道是否有一个推荐的解决方案来获得这种结果(即使用我的模板参数类编写一次默认实现).

c++ templates c++-concepts

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

C++范围-v3 concepts :: valid_expr检查,尾随",42"

继续我读取range-v3库,我意识到关于模板类型的有效表达式的所有检查都有一个拖尾",42"表达式,我想知道它的目的是什么.例如:

namespace concepts {
    constexpr struct valid_expr
    {
       template<typename... T>
       void operator()(T&&...) const;
    };
}

struct ExplicitlyConvertibleTo
{
   template<typename From, typename To>
   auto requires_(From (&from)()) -> decltype(
       concepts::valid_expr(
           ((void) static_cast<To>(from()), 42)
   ));
};
Run Code Online (Sandbox Code Playgroud)

我理解该实现的一些要点,比如强制使用逗号运算符的内括号,避免逗号运算符的一些重载等的void-casting,但为什么不只是简单地写一些像?

concepts::valid_expr(static_cast<To>(from()));
Run Code Online (Sandbox Code Playgroud)

c++ comma-operator template-meta-programming c++-concepts

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

Windows上的C++ 17是否与ubuntu上的C++ 17一致?

我试图移植一些我在ubuntu上制作的C++ 17代码(gnu ++ 11)

typedef boost::variant<int, float, std::string > Variant;
using Func = std::function<std::vector<unsigned char>(std::vector<Variant>)>;  

void addexecutorfunc( Func callback, const auto&...args )
{
    std::vector<Variant> vec = {args...}; 
    executor.add(vec, std::move(callback));
}
Run Code Online (Sandbox Code Playgroud)

这段代码在ubuntu上编译和工作正常,但是当尝试使用visual studio 2017(v141)[ISO C++最新草案标准(/ std:c ++ latest)]在Windows上编译时,我得到以下内容:

错误C3533:参数不能包含'auto'的类型

我想也许它与在当前的C++ 17版本中没有实现的Concepts lite有关,或者这是错的?

如果我可以设置编译器使用auto作为参数和参数包,那么这将是最好的,但如果这是不可能的,那么我将不得不重写我的代码遵循C++ 17 windows标准 - 任何关于如何做的建议这没有在模板地狱中结束

c++ visual-studio c++-concepts c++17

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