相关疑难解决方法(0)

C++20 概念:如何在`requires` 子句中引用类名?

我有一个 CRTP 课程

template <typename T>
class Wrapper
{
  // ...
};
Run Code Online (Sandbox Code Playgroud)

旨在导出为

class Type : Wrapper<Type>
{
  // ...
};
Run Code Online (Sandbox Code Playgroud)

我想通过对模板参数施加约束来强制执行T。有一个friend技巧可以做到这一点,但我认为在概念时代应该有更好的方法。我的第一次尝试是

#include <concepts>

template <typename T>
  requires std::derived_from<T, Wrapper<T>>
class Wrapper
{
  // ...
};
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为我指的是Wrapper在声明之前。我发现了一些不完全令人满意的解决方法。我可以将约束添加到构造函数

Wrapper() requires std::derived_from<T, Wrapper<T>>;
Run Code Online (Sandbox Code Playgroud)

但是如果我有更多的构造函数也必须受到约束,这就不方便了。我可以用析构函数来做

~Wrapper() requires std::derived_from<T, Wrapper<T>> = default;
Run Code Online (Sandbox Code Playgroud)

但是声明析构函数只是为了穿上它感觉有点傻requires

我想知道是否有更好,更惯用的方法来做到这一点。特别是,虽然这些方法似乎有效(在 gcc 10 上测试过),但一件令人不满意的事情是,如果我Type从派生Wrapper<OtherType>,那么只有在我实例化 时才会引发错误Type。是否有可能在定义点出现错误Type

c++ c++-concepts

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

使用CRTP时如何避免错误?

使用CRTP有时我会编写如下代码:

// this was written first
struct Foo : Base<Foo, ...>
{
   ...
};

// this was copy-pasted from Foo some days later
struct Bar : Base<Foo, ...>
{
   ...
};
Run Code Online (Sandbox Code Playgroud)

并且很难理解出现了什么问题,直到我在调试器中跟踪代码并看到Bar的成员未被使用Base.

如何在编译时显示此错误?

(我使用MSVC2010,所以我可以使用一些C++ 0x功能和MSVC语言扩展)

c++ crtp

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

如何实现编译时检查转发在CRTP中是否有效?

我有一个普通的旧CRPT(请不要因访问限制而分心 - 问题与他们无关):

 template<class Derived>
 class Base {
     void MethodToOverride()
     {
        // generic stuff here
     }
     void ProblematicMethod()
     {
         static_cast<Derived*>(this)->MethodToOverride();
     } 
 };
Run Code Online (Sandbox Code Playgroud)

像往常一样打算像这样使用:

 class ConcreteDerived : public Base<ConcreteDerived> {
     void MethodToOverride()
     {
        //custom stuff here, then maybe
        Base::MethodToOverride();
     }
 };
Run Code Online (Sandbox Code Playgroud)

现在static_cast困扰我了.我需要一个向下投射(不是向上投射),所以我必须使用一个明确的演员.在所有合理的情况下,强制转换都是有效的,因为当前对象确实是派生类.

但是如果我以某种方式改变层次结构并且演员现在变得无效呢?

我可以以某种方式强制执行编译时检查,在这种情况下显式向下转换有效吗?

c++ casting crtp static-cast upcasting

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

防止兄弟结构的平等比较

为了代码重用的目的,我有许多派生自同一个基础的结构,但我不想要任何形式的多态.

struct B {
    int field;
    void doStuff() {}
    bool operator==(const B& b) {
        return field == b.field;
    }
};

struct D1 : public B {
    D1(int field) : B{field} {}
};
struct D2 : public B {
    D2(int field) : B{field} {}
};
Run Code Online (Sandbox Code Playgroud)

结构D1D2(以及更类似的结构)派生自B共享公共字段和方法,因此我不需要在每个派生类中复制这些字段和方法.

结构B永远不会被实例化; 我只使用D1和的实例D2.此外,D1并且D2根本不应该彼此互动.从本质上讲,我不希望任何多态行为:D1并且D2,出于所有目的,应该充当不相关的结构.

我希望任何D1与其他D1s 相比较的平等,以及任何D2与其他D2s 相比较的平等.由于D1并且 …

c++ inheritance siblings c++17

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