簡體   English   中英

為什么在 consteval 構造函數中編譯時不知道“this”?

[英]Why isn't “this” known at compile time in a consteval constructor?

我正在編寫一個 class 來包裝與設備一起使用的基於 C 的庫的一部分,其中每個設備都配置有用於處理數據的回調 function 指針。 將為每個設備創建一個MyClass實例。 見下文:

struct DeviceConfig {
    void (*callback)(char *data);
};

class MyClass {
private:
    DeviceConfig config;

public:
    void myCallback(char *data);

    MyClass() {
        // Would like to set config.callback so that a call to it will result in a call of this->myCallback(data).
    }
};

由於捕獲 lambda 無法轉換為 function 指針,因此我嘗試了以下解決方法:

template<MyClass *MC>
auto binder() {
    return [](char *data) { MC->myCallback(data); };
}

MyClass::MyClass() {
    config.callback = binder<this>();
}

但是,編譯器(最新的 GCC)不喜歡在構造函數中使用binder ,因為this在編譯時不一定知道,盡管我知道MyClass的實例只會在編譯時聲明。

C++20 引入了“必須生成編譯時常量”的consteval函數(和構造函數)。 . 但是,將consteval添加到構造函數和/或binder器不會影響編譯器的 output。 constexpr也不會改變任何事情。

如果 object 可以在編譯時初始化,為什么在編譯時也不能知道對象的this呢? 以上可以通過其他方式實現嗎?

構造函數是函數,就像其他函數一樣。 與其他函數相比,它們的特權很少,其參數的常量表達式行為不是其中之一。

this本質上是所有非靜態成員函數的參數。 參數永遠不是常量表達式 因此, this不能在需要常量表達式的上下文中使用。 如何創建 class 實例並不重要。 不管你怎么稱呼它。 constexpr/consteval函數的參數絕不是常量表達式,包括this

接受的答案確實解釋this為什么不能在構造函數中使用它; 但是,我還詢問是否有解決方法來實現我想要的。 我找到了一種解決方法,並在此處的另一個 StackOverflow 帖子中分享了該工作。

為了節省點擊,這是我的代碼的最后一次迭代:

struct DeviceConfig {
    void (*callback)(const char *);
};

template<auto& v, auto f>
constexpr auto member_callback = [](auto... args) { (v.*f)(args...); };

class MyClass {
private:
    DeviceConfig config;

public:
    consteval MyClass(const DeviceConfig& cfg = {}) :
        config(cfg) {}

    template<MyClass& MC>
    constexpr static MyClass& init() {
        MC.config.callback = member_callback<MC, &MyClass::myCallback>;
        return MC;
    }

    void myCallback(const char *data);
};

int main()
{
    constinit static MyClass mc = (mc = MyClass(), MyClass::init<mc>());
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM