有没有一种方法可以static_assert在模板参数中给出的变量参考?

发布于 2025-02-08 04:42:27 字数 570 浏览 2 评论 0 原文

struct Config 
{
    int version = 1; 
};

template<Config& config /* , ... */>
struct Peripheral
{
    const Config config_ = config;
    static_assert(config_.version > 1, "Config version must be greater than 1");
    /* ... */
};

Config myConfig;

int main()
{
    myConfig.version = 5;
    Peripheral<myConfig> peripheral;
}

我想在编译时检查我的模板的配置是否正确。

因此,我试图将我的引用引用为恒定实例,以便在static_assert中使用它,但是我会发现错误:“非静态数据成员的使用无效...'

是否有一种方法可以检查值在这种情况下,在编译时间时的非型参数?还是您还有其他建议可以实现这一目标?

struct Config 
{
    int version = 1; 
};

template<Config& config /* , ... */>
struct Peripheral
{
    const Config config_ = config;
    static_assert(config_.version > 1, "Config version must be greater than 1");
    /* ... */
};

Config myConfig;

int main()
{
    myConfig.version = 5;
    Peripheral<myConfig> peripheral;
}

I want to check at compile-time if the configurations given to my template are correct.

So I am trying to cast my reference to a constant instance in order to try to use it in my static_assert, but I get the error: 'invalid use of non-static data member ...'

Is there a way to check the values of a non-type parameter at compile-time in this case? Or do you have other suggestions to achieve this goal?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

[浮城] 2025-02-15 04:42:27

如果要在编译时使用 myConfig value 初始化器。然后是静态存储持续时间变量,然后是次要的:

constexpr Config myConfig = { .version = 5 };
// alternatively before C++20 for example
// constexpr Config myConfig = { 5 };
/*...*/
Peripheral<myConfig> peripheral;

然后,模板应采用参数概述,而不是征用参数,并且您应该直接在 static_assert 中直接使用该模板参数

template<Config config /* , ... */>
struct Peripheral
{
    static_assert(config.version > 1, "Config version must be greater than 1");
    /* ... */
};

。在 config 中的其他内容上,或者如果您不使用C ++ 20或更高版本,则可能不允许使用该类型作为副价值模板参数。在这种情况下,您可以继续使用参考参数(尽管我不确定这是好设计),但是您需要将其制作 const config&amp; 而不是匹配 const constexpr 暗示。在这种情况下,重要的是 myConfig 具有静态存储持续时间(特别是可以在名称空间范围内声明为 static> static 数据成员,也可以自AS data成员>静态本地变量)。

如果要继续使用本地 config _ 要断言的副本,则该副本也应标记为 constexpr const 不足以进行因此,在编译时的变量)及其也必须标记为 static (因为非 - static> static 数据成员不能声明 constexpr )。

模板参数的值和 static_assert 无法(可能)在运行时确定,因此 myconfig.version = 5; 永远无法使用。

If you want the value of myConfig to be used at compile-time, then you should mark it constexpr and give it its value directly in the initializer. Whether it is a static or automatic storage duration variable is then secondary:

constexpr Config myConfig = { .version = 5 };
// alternatively before C++20 for example
// constexpr Config myConfig = { 5 };
/*...*/
Peripheral<myConfig> peripheral;

Then the template should take the parameter by-value, not by-reference, and you should use that template parameter directly in the static_assert:

template<Config config /* , ... */>
struct Peripheral
{
    static_assert(config.version > 1, "Config version must be greater than 1");
    /* ... */
};

Depending on what else is in Config or if you are not using C++20 or later, the type might not be allowed as by-value template parameter. In that case you can keep using a reference parameter (although I am not sure that this is good design) but you would need to make it const Config& instead to match the const implied by constexpr. In this case it does matter that myConfig has static storage duration (specifically it may be declared at namespace scope, as a static data member or since C++17 as static local variable).

If you want to keep on using a local config_ copy to assert on, that copy should also be marked constexpr (const is not enough to make a variable usable at compile-time) and hence must also be marked static (because non-static data members cannot be declared constexpr).

The value of the template parameter and static_assert cannot be (potentially) determined at run-time, so myConfig.version = 5; will never work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文