标签: explicit-object-parameter

与 C++23 结合推导具有自动返回类型的 this 和转换运算符?

我最近注意到一个关于 C++23推导此功能的奇怪问题。

S假设我们有一个带有简单转换运算符的结构:

struct S {
  operator int() { return 42; }
};

int i = S{};
Run Code Online (Sandbox Code Playgroud)

由于42是 类型int,我们可以将转换运算符的返回类型指定为auto,例如:

struct S {
  operator auto() { return 42; }
};

int i = S{};
Run Code Online (Sandbox Code Playgroud)

完全没问题。如果我们应用C++23来推导它的这个特性,那就是:

struct S {
  operator auto(this S) { return 42; }
};

int i = S{};
Run Code Online (Sandbox Code Playgroud)

这也完全没问题。但是,当我替换this Sthis auto

struct S {
  operator auto(this auto) { return 42; } …
Run Code Online (Sandbox Code Playgroud)

c++ language-lawyer type-deduction c++23 explicit-object-parameter

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

如何在成员函数内完美转发`*this`对象

是否可以*this在成员函数内完美转发对象?如果是的话,我们该怎么做呢?如果不是,那么为什么不呢?我们有哪些替代方案可以达到同样的效果。

请参阅下面的代码片段以更好地理解该问题。

class Experiment {
public:
  double i, j;
  Experiment(double p_i = 0, double p_j = 0) : i(p_i), j(p_j) {}

  double sum() { return i + j + someConstant(); }

  double someConstant() && { return 10; }

  double someConstant() & { return 100; }
};

int main() {
  Experiment E(3, 5);
  std::cout << std::move(E).sum() << "\n";  // prints: 108
  std::cout << E.sum() << "\n";             // prints: 108
}
Run Code Online (Sandbox Code Playgroud)

如果我们认为*this成员函数内的对象double sum()始终是左值或x值(因此是左值),则此输出似乎是预期的。请确认这是否属实。

如何才能完美地将*this对象转发给成员函数 …

c++ overload-resolution c++11 explicit-object-parameter

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

C++23 中显式 *this 对象参数提供什么?

在C++23中,推导这一点最终被添加到标准中。

根据我从提案中读到的内容,它开辟了一种创建 mixins 的新方法,并且可以创建递归 lambda。

但是我很困惑,如果这个参数在不使用模板的情况下创建“副本”,因为没有引用,或者显式this参数是否有自己的值类别规则?

自从:

struct hello {
  void func() {}
};
Run Code Online (Sandbox Code Playgroud)

可能相当于:

struct hello {
  void func(this hello) {}
};
Run Code Online (Sandbox Code Playgroud)

但它们的类型不同,因为对于&hello::func,第一个给出void(hello::*)(),而第二个给出void(*)(hello)

例如,我有这个简单的功能:

struct hello {
  int data;
  void func(this hello self) {
    self.data = 22;
  }
};
Run Code Online (Sandbox Code Playgroud)

参数不需要是引用来更改类型this的值吗?hello或者它基本上和以前一样遵循成员函数的 cv-ref 限定符规则?

c++ this c++23 explicit-object-parameter

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

具有显式对象参数和 std::invoke_result_t 的 Lambda

如何获取具有使用推导此签名的 lambda 的返回类型std::invoke_result_t

auto lambda = [](this auto& self, int x) -> int {
    return x;
};  
  
auto x = std::invoke_result_t<decltype(lambda), int>{}; //won't compile
Run Code Online (Sandbox Code Playgroud)

我是否需要以某种方式指定 self 参数std::invoke_result_t

我尝试过没有“推导这一点”,并且上面的示例有效。

编辑: 编译器资源管理器链接

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

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

避免重复 const 和非 const 版本的 getter?

struct BananaHolder
{
    vector<Banana>& getBananas();
    const vector<Banana>& getBananas() const;
};
Run Code Online (Sandbox Code Playgroud)

我的课程充满了这种重复。

有没有更干净、更优雅的替代方案?

c++ getter c++11 function-qualifier explicit-object-parameter

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

显式对象参数是否允许可转换类型?

来自提案的 \xc2\xa74.2.7 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p0847r7.html#pathological-cases

\n

它说:

\n
\n

这些更不可能是真正有用的代码。在此示例中,B既不能转换为Aint,因此这两个函数甚至都不能使用普通成员语法调用。但是,您可以获取指向此类函数的指针并通过该指针调用它们。(&B::bar)(42)有效,如果奇怪,请致电。

\n
\n

但是,它没有指定标准是否不允许将 type-of-self 的显式对象参数隐式转换为特定的另一种类型。

\n
struct A { };\nstruct B {\n    void foo(this A&);\n    void bar(this int);\n};\n
Run Code Online (Sandbox Code Playgroud)\n

这是否意味着:

\n
struct A { };\nstruct B {\n  operator A() const noexcept;\n  void foo(this A);\n};\n\n// ...\n// \'&B::foo\' is of type function pointer not pointer to member function\n// because it uses explicit object parameter.\n(&B::foo)(A{}); \n(&B::foo)(B{});\nB{}.foo(); // will work?\n
Run Code Online (Sandbox Code Playgroud)\n

将工作?

\n

在另一种情况下,这是一个 lambda。由于 lambda 的类型是不可言说的并且始终是相关的。那上面的案例呢?(这个无捕获 lambda …

c++ this type-conversion c++23 explicit-object-parameter

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

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
查看次数

如何避免在易失性类中重复方法

假设我有以下非常简单的类:

class A
{
public:
    static constexpr A make() { return A{}; }

    constexpr A() : _v(0) {}

    constexpr A& setV(int v) { _v = v; return *this; }

private:
    int _v;
};
Run Code Online (Sandbox Code Playgroud)

如果我尝试按如下方式使用它:

int main()
{
    volatile A a1;
    a1.setV(10);

    //OR

    //The optimizer will optimize this chain of constexpr calls into a single "store" instruction
    a1 = A::make().setV(10); //More chaining here

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该代码将无法编译。

我理解为什么这是真的,基于:定义易失性类对象

我知道解决方案是添加一个额外的方法,如下所示:

class A
{
public:
    constexpr A() : _v(0) {}

    volatile A& …
Run Code Online (Sandbox Code Playgroud)

c++ volatile member-functions explicit-object-parameter

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

为什么在函数指针中使用显式对象参数会出现语法错误?

因此,在我正在处理的项目中尝试对函数指针使用显式对象参数时,我遇到了问题。乍一看,代码在语法上似乎很好,但由于这是一个新功能,我在网上找不到太多信息,所以我不知道为什么会出现随机语法错误。具体来说,错误是“语法错误:')'”

我唯一真正的猜测是,这是某种 MSVC 不完整性/错误,在这种情况下我可能不得不切换到不同的编译器。

///base.h
///...
#include <map>

template <class s>
using FunctionMap = std::map<std::string,void(*)(this s& self)>;
                                            ///^ Syntax Error Here

class base{
//...
public:
   ///Get Map of fPtr
   template <class Self>
   FunctionMap<Self>* get_scripts(this const Self& self);
}
Run Code Online (Sandbox Code Playgroud)

我预计它可以编译,但它不断出现语法错误。我知道显式对象参数仅在 MSVC 中部分实现。

c++ visual-c++ c++23 explicit-object-parameter

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