标签: c++-concepts

C++20 如何拥有需要稍后定义的自由函数的概念

MyConcept假设我有一个描述通用算法要求的概念algo。在下面的示例代码中,唯一的要求是一个自由函数my_free_function,它接受一个MyConcept类型并返回相同的类型,并且存在三种满足要求的类型。

template<class T>
concept MyConcept = requires (T a) {
    { my_free_function(a) } -> std::same_as<T>;
};

template<MyConcept T>
auto algo(T& a) {
    return my_free_function(a);
}

namespace baz {
struct bar {};
bar my_free_function(bar) { return bar{}; }
}; // baz

unsigned long my_free_function(unsigned long) { return 42; }

namespace caz {
using NativeU64 = unsigned long;
NativeU64 my_free_function(NativeU64) { return NativeU64{42ul}; }
}; // caz
Run Code Online (Sandbox Code Playgroud)

我的挑战是,为了获得以下调用来编译 NativeU64 和 unsigned long,我必须在概念和算法之前定义 my_free_function 。这是唯一的选择吗?我当前的代码组织和依赖结构依赖于能够在头文件中定义概念和算法,编译器在看到满足要求的定义之前会使用这些概念和算法。

auto …
Run Code Online (Sandbox Code Playgroud)

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

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

C++:如何编写一个要求构造函数为 noexcept 的概念?

如何编写一个要求类具有noexcept构造函数的概念?例如,以下内容static_assert在 Clang 15.0.7 中是正确的,尽管我觉得不应该。

class Ragdoll {
    int age_ = -1;
public:
    Ragdoll(int age) /* noexcept */ : age_(age) {}

    int meow() const;
    int lose_hair();
};

template<typename Cat>
concept cat = requires(Cat cat) {
    noexcept(Cat{42});
    { cat.meow() } -> std::same_as<int>;
};

static_assert(cat<Ragdoll>);
Run Code Online (Sandbox Code Playgroud)

noexcept那么这个表达式在概念中到底在做什么呢?(也请随意链接任何好的概念教程)

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

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

C++ 函数调用概念不明确

我有一个 C++ 宏,我想用它来调用一个重载的函数模板。我希望这些函数模板之一仅接受浮点值,而另一个函数模板将接受其他所有内容。

以下是我使用 C++ 20 在https://cpp.sh/中运行的代码:

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

template< typename T>
concept NotFloatingPoint = requires
{
    !std::is_same_v<T, double> || !std::is_same_v<T, float>;
};

template< NotFloatingPoint T, NotFloatingPoint U, bool isDistanceType_ = false >
void ProcConstantConfigForce( T& value_ )
{
    std::cout << "Inside ProcConstantConfigForce()\n";
    std::cout << value_;
}

template< typename T>
concept FloatingPoint = requires
{
    std::is_same_v<T, double> || std::is_same_v<T, float>;
};

template< FloatingPoint T, FloatingPoint U, bool isDistanceType_ = false > …
Run Code Online (Sandbox Code Playgroud)

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

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

在模板参数中更改bool值的类型

我正在逐步学习模板,我认为这是我当前项目需要做的最后一件事:

template < typename Object, bool Shared>
class  Foo {

  private:
    struct SubFoo {

      //if Shared == true -> FooShared  foo;
      //if Shared == false -> FooBasic  foo;
      ???          foo;
      Object       data;
    };
};
Run Code Online (Sandbox Code Playgroud)

我知道MagicType foo;这样做不会那么容易,不用担心修改代码.我没有C++限制(g ++ 6.2,我想知道如何获得g ++ 7)所以即使是概念也是受欢迎的.

c++ templates c++-concepts

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

编译时评估代码中的重言式是否保证被执行/优化掉?

编译器是否保证评估环境constexpr"tautologies"(例如始终truefalse分别)的布尔表达式constexpr

最小示例/说明

例如,在以下代码片段(在标有 的行(1))中,我在constexpr环境中调用了一个函数,我打算在non-constexpr传递函数时导致编译时错误。至少我使用的编译器 ( g++-10.0) 是这样做的,即使它也可以意识到表达式总是true不计算它。我问这个问题的原因是 - 据我所知 - 在非 constepxr 上下文中,像这样的表达式i >= std::numeric_limits<int>::min()被优化trueint i.

#include <limits>
constexpr int example_function() { return 1;}
constexpr bool compileTimeErrorDesired = example_function() || true; // (1)
Run Code Online (Sandbox Code Playgroud)

应用实例

如果(1) 保证in 的行为,则可以在 aconcept中使用它,以执行不同的代码,具体取决于是否可以在编译时评估作为模板参数提供的函数。我实现了一个非常短的 ( 7 lines-of-code) 示例,它在编译器资源管理器中完全做到这一点。

如果使用非 constexpr 函数调用,行 (1) …

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

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

为什么 std::vector::iterator 不是连续迭代器?

按照cppref页面std::vector

iterator 传统随机访问迭代器

同样来自另一个cppref 页面

以下标准库类型是LegacyContiguousIterators

vector::iterator 对于 bool 以外的 value_type。

哪个是正确的?

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

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

当 std::is_trivial_v&lt;T&gt; 为真时 T 可以有析构函数吗?

#include <type_traits>

struct A
{
    ~A() {}
};

int main()
{
    static_assert(std::is_trivial_v<A>); // error   
}
Run Code Online (Sandbox Code Playgroud)

它似乎很明显,std::is_trivial_v<A>将是false如果A有一个析构函数。

但是,从 的cppref 页面std::is_trivial,没有什么要求A一定不能有析构函数。

什么时候可以 T 有析构函数 std::is_trivial_v<T>

c++ standards destructor type-traits c++-concepts

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

概念:要求类方法返回类型是同一类的嵌套类型

我正在尝试实现以下概念

template<typename T>
concept GameLogic = requires(T a)  {
    typename T::StateType;
    typename T::EventType;
    { a.initialState()->T::StateType }; // <-- relevant bit
};
Run Code Online (Sandbox Code Playgroud)

我想强制initialState()返回类型是同一类的嵌套类型。

概念定义不会引发错误(gcc 9.2),但以下实现GameLogic无法满足要求:

class SimpleGameLogic {
public:

    using StateType = SimpleState;
    using EventType = SimpleEvent;

    StateType initialState() {
        return _initialState;
    }

private:
    StateType _initialState;

};
Run Code Online (Sandbox Code Playgroud)

我已经尝试了上述语法的一些变体,但找不到正确的语法...或者这可能尚未实现?我究竟做错了什么?

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

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

C++ 概念中的价值评估

如何正确评估概念声明/requires 子句中的值?

考虑一个概念is_red,检查给定类型是否具有color设置为 的静态 cx 成员/*undefined*/::red,其中枚举中的`/ undefined /;

template <typename T>
concept is_red = requires(T) {
   { T::color == decltype(T::color)::red };
};
Run Code Online (Sandbox Code Playgroud)

这显然是错误的,因为它只检查合成是否定义良好。
因此,这不会按预期工作:

namespace apple {
   enum colors{red, green, yellow };

   struct granny_smith{
      constexpr static auto color = colors::green;
   };
}

static_assert(is_red<apple::granny_smith>); // should fail, but it does not using the previous concept implementation
Run Code Online (Sandbox Code Playgroud)

请参阅此处有关 godbolt 的实例。

这是我目前评估概念价值的方式:

template <bool condition>
using if_t = std::conditional_t<condition, std::true_type, std::false_type>;

template <typename T>
concept is_red …
Run Code Online (Sandbox Code Playgroud)

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

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

使用抽象基类来强制模板参数类型的公共接口是一种不好的做法吗?

我是模板编程的新手,并且偶然发现了这个习惯用法。例如,类似:

class FooBase {
 public:
  virtual void do_something() = 0;
};

template <class Foo> // Foo is derived from FooBase
void g(Foo& foo) {
  static_assert(std::is_base_of<FooBase, Foo>::value);
  // ...
  foo.do_something();
  // ...
}
Run Code Online (Sandbox Code Playgroud)

在我看来,这种模式很有用,因为:

  1. 纯虚函数声明具有显式签名;与 C++20 概念requires子句(如果可用的话)相比,指定属性、参数和返回类型很容易。
  2. 这是很好的文档;只需阅读FooBase标头即可清楚定义新 Foo 类的要求。
  3. 可以将所有 Foo 的通用功能重构到同一个FooBase类中。

但是我担心使用的性能影响virtual函数对性能的影响。我的理解是运行时没有成本,因为该函数是从派生类调用的;但链接器将无法内联该函数。

另一个缺点是不允许虚拟模板功能。

最后,我担心这可能是一种代码味道,因为它使用运行时多态性功能来执行静态检查。C++20 概念可能是执行此操作的“正确”方法,但由于上述三个原因,它们似乎不太方便。

c++ polymorphism templates c++-concepts

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