模板参数constexpr的显式指定参数无效 [英] Invalid explicitly-specified argument for template parameter which is constexpr

查看:160
本文介绍了模板参数constexpr的显式指定参数无效的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 static_loop 构造

template <std::size_t n, typename F> void static_loop(F&& f) {
    static_assert(n <= 8 && "static loop size should <= 8");
    if constexpr (n >= 8)
        f(std::integral_constant<size_t, n - 8>());
    if constexpr (n >= 7)
        f(std::integral_constant<size_t, n - 7>());
    if constexpr (n >= 6)
        f(std::integral_constant<size_t, n - 6>());
    if constexpr (n >= 5)
        f(std::integral_constant<size_t, n - 5>());
    if constexpr (n >= 4)
        f(std::integral_constant<size_t, n - 4>());
    if constexpr (n >= 3)
        f(std::integral_constant<size_t, n - 3>());
    if constexpr (n >= 2)
        f(std::integral_constant<size_t, n - 2>());
    if constexpr (n >= 1)
        f(std::integral_constant<size_t, n - 1>());
}


template <typename T> constexpr size_t tupleSize(T) { return tuple_size_v<T>; }
struct A {
    int a;
    int b;
    void run() {
        auto ab = std::make_tuple(std::ref(a), std::ref(b));
        static_loop<tupleSize(ab)>([&](auto i) { std::get<i>(ab) = i; });
        std::cout << a << " " << b << std::endl;
    }
};

但是,它无法遍历上面列出的元组。

However, it fails to iterate over a tuple as listed above.

实时螺栓示例

推荐答案

建议:尝试

// .........VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
static_loop<std::tuple_size_v<decltype(ab)>>([&](auto i) { std::get<i>(ab) = i; });

我的意思是...您不能使用 ab (作为值),用一个常量表达式表示,因为未定义 ab constexpr

I mean... you can't use ab (as value), in a constant expression, because ab isn't defined constexpr.

您不能定义它 constexpr ,因为它是使用 std :: ref()<初始化的/ code>不是 constexpr

And you can't define it constexpr because it's initialized using std::ref() that isn't constexpr.

但是您对<$ c不感兴趣$ c> ab 作为值来获取其类型的大小;您只对 ab 类型感兴趣;因此您可以通过 decltype(ab)

But you're not interested in ab as value to get the size of its type; you're interested only in ab type; so you can pass through decltype(ab).

-编辑-

非主题建议。

而不是 static_loop(),您可以使用基于 std :: index_sequence 的经典方法(以及模板折叠,从C ++ 17开始可用)。

Instead of static_loop(), you can use the classic way based on std::index_sequence (and template folding, available starting from C++17).

我的意思是...如果您定义 run_1()函数(使用 run_1_helper()助手)

I mean... if you define a run_1() function (with run_1_helper() helper) as follows

template <typename F, typename ... Ts, std::size_t ... Is>
void run_1_helper (F const & f, std::tuple<Ts...> & t, std::index_sequence<Is...> const)
 { (f(std::get<Is>(t), Is), ...); }

template <typename F, typename ... Ts>
void run_1 (F const & f, std::tuple<Ts...> & t)
 { run_1_helper(f, t, std::index_sequence_for<Ts...>{}); }

您可以按以下方式编写 A

you can write A as follows

struct A {
    int a;
    int b;
    void run() {
        auto ab = std::make_tuple(std::ref(a), std::ref(b));
        run_1([](auto & v, auto i){ v = i; }, ab);
        std::cout << a << " " << b << std::endl;
    }
};

或者,也许更好,只需使用 std :: apply(),如下所示

Or, maybe better, simply using std::apply(), as follows

struct A {
    int a;
    int b;
    void run() {
        auto ab = std::make_tuple(std::ref(a), std::ref(b));
        int i { -1 };
        std::apply([&](auto & ... vs){ ((vs = ++i), ...); }, ab);
        std::cout << a << " " << b << std::endl;
    }
};

这篇关于模板参数constexpr的显式指定参数无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆