小编Ami*_*rsh的帖子

使用概念检查类型 T 是否具有字段 F

以下concept检查类型T是否具有公共字段foo

template<typename T>               
concept has_field_foo = requires { 
    T::foo;                       
};
Run Code Online (Sandbox Code Playgroud)

有没有办法实现一个泛型concept来检查类型T是否有一个公共字段F,类似于(伪代码......字段F不能像这样传递):

template<typename T, typename F>               
concept has_field = requires { 
    T::F;
};
Run Code Online (Sandbox Code Playgroud)

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

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

为什么 C++20 不使用 `requires` 来限制 atomic&lt;T&gt; 的 T?

一个通用的std::atomic<T>,需要有一个T可复制构造复制可分配

[atomics.types.generic]/1

如果存在以下任一情况,则程序格式错误

(1.1) is_­trivially_­copyable_­v<T>,

(1.2) is_­copy_­constructible_­v<T>,

(1.3) is_­move_­constructible_­v<T>,

(1.4) is_­copy_­assignable_­v<T>,

或 (1.5) is_­move_­assignable_­v<T>

false

以上对于 C++20 来说并不陌生。编译器可能会static_assert为不符合标准的 T 发出错误。

但是,C++20 可以在语法中使用形式约束requires来正式要求上述内容作为类型的一部分,例如:

template< class T > requires
    std::is_trivially_copyable_v<T> &&
    std::is_copy_constructible_v<T> &&
    std::is_move_constructible_v<T> &&
    std::is_copy_assignable_v<T> &&
    std::is_move_assignable_v<T>
struct atomic { ... };
Run Code Online (Sandbox Code Playgroud)

C++20 是否有理由避免为此目的使用形式约束


编辑: @TC在下面的回答中正确指出:

对于std::atomic特别是,限制主模板只是不是一种选择,给定atomic<shared_ptr<T>>atomic<weak_ptr<T>>特在C ++ 20添加的。

有一个选项建议:

也许你可以做一些更有趣的事情(比如一个未定义和不受约束的主模板加上一个受约束的部分特化),但它增加的价值很小。

好吧,还有另一种选择,不需要 …

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

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

C++中方法和对象选择的静态多态性

尝试在没有基类和虚拟调用的情况下获取编译时方法和对象选择.

情况如下:

struct A {
    void f1()const { cout << "A::f1" << endl;}
    void f2()const { cout << "A::f2" << endl;}
};

struct B {
    void f1()const { cout << "B::f1" << endl;}
    void f2()const { cout << "B::f2" << endl;}
};

class Holder {
    A* _a = nullptr;
    B* _b = nullptr;
public:
    Holder(A* a): _a(a) {}
    Holder(B* b): _b(b) {}
    void f1()const {
        if(_a)       _a->f1();
        else if(_b)  _b->f1();
    }
    void f2()const {
        if(_a)       _a->f2();
        else if(_b)  _b->f2();
    } …
Run Code Online (Sandbox Code Playgroud)

c++ macros templates boost-variant static-polymorphism

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

C++ 概念的通配符表示“接受此模板参数的任何内容”

有没有办法允许concept使用模板参数,可以使用提供的任何模板参数?

\n

即模板参数占位符的某种通配符魔法?

\n

一个使用示例:

\n
template<class Me, class TestAgainst>\nconcept derived_from_or_same_as = \n    std::same_as<Me, TestAgainst> ||\n    std::derived_from<Me, TestAgainst>;\n
Run Code Online (Sandbox Code Playgroud)\n

需要上面的内容是因为不幸的是,原始类型的 行为与和 的类类型不同。is_base_ofderived_from

\n

现在我们可以定义一个Pair concept来检查提供的类型:

\n
template<class P, class First, class Second>\nconcept Pair = requires(P p) {\n    requires derived_from_or_same_as<decltype(p.first), First>;\n    requires derived_from_or_same_as<decltype(p.second), Second>;\n};\n
Run Code Online (Sandbox Code Playgroud)\n

用例 [a] - 接受任何有效的As或As子类型对:

\n
// this works well\nvoid doWithPairOfA(const Pair<A, A> auto& p) { /* */ }\n
Run Code Online (Sandbox Code Playgroud)\n

用例 …

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

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

P0847 推断这一点 - 它可以允许通用克隆而不需要 CRTP 吗?

P0847提出了对成员函数使用显式参数的可能性this

除了该提案带来的其他好处之外,CRTP 还为没有 C、R 甚至 T 的 CRTP带来了巨大的新可能性。

在 C++ 中实现泛型的常见做法clone是基于 CRTP,例如请参阅此 SO 帖子

鉴于我们需要clonevirtual或者至少表现为虚拟),允许:

Shape* pCopy = pShape->clone(); // get a copy of the correct runtime type
Run Code Online (Sandbox Code Playgroud)

并且鉴于建议不应声明具有显式 this 参数的成员函数virtual

是否仍然有办法使用 P0847 来实现具有动态行为且无需 CRTP 的通用克隆

c++ crtp type-deduction c++23 explicit-object-parameter

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

std::reverse_iterator 如何在开始之前保留一个?

这是一个使用以下代码的示例std::reverse_iterator

template<typename T, size_t SIZE>
class Stack {
    T arr[SIZE];
    size_t pos = 0;
public:
    T pop() {
        return arr[--pos];
    }
    Stack& push(const T& t) {
        arr[pos++] = t;
        return *this;
    }
    auto begin() {
        return std::reverse_iterator(arr+pos);
    }
    auto end() {
        return std::reverse_iterator(arr);
                // ^ does reverse_iterator take this `one back`? how?
    }
};

int main() {
    Stack<int, 4> s;
    s.push(5).push(15).push(25).push(35);
    for(int val: s) {
        std::cout << val << ' ';
    }
}

// output is as expected: …
Run Code Online (Sandbox Code Playgroud)

c++ iterator reverse-iterator

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