简体   繁体   中英

Why can't we use compile-time 'variables' in consteval functions as template parameters?

I was testing this code ( https://godbolt.org/z/fe6hhbeqW )...

// Returns the nth type in a parameter pack of types (ommited for clarity)
//   template <std::size_t N, typename...Ts>
//   nth_type{}

template <typename... Ts>
struct Typelist{
    template <typename T>
    consteval static std::size_t pos() noexcept { 
        for(std::size_t i{}; i < sizeof...(Ts); ++i) {
            using TN = nth_type_t<i, Ts...>;
            if (std::is_same_v<T, TN>) 
                return i;
        }
        return sizeof...(Ts);
    }
};

and I was puzzled for it not working. GCC and clang agree on i not being a constant expression, so they refuse to let me pass it as a template parameter. However, i is clearly known at compile-time so, to my limited understanding, the compiler shouldn't have any problem to use it to instantiate the template.

Is there a reason for this not to work? Will it work in the future? I have tested with trunk versions of both compilers, with same result.

It doesn't matter that i is guaranteed to be evaluated only at compile-time when its value is known in an abstract sense.

It also doesn't matter whether the function is consteval or constexpr or none of these.

The language is still statically typed and nth_type_t<i, Ts...>; must in any given instantiation of the function refer to exactly one type. If i can change in the for loop, that is not possible to guarantee.

The language requires that the expression i when used as template argument is by itself a constant expression, independently of whether the whole function body can only be evaluated as part of a larger constant expression. But i is neither declared constexpr , nor declared const with constant initializer.

While this is not possible currently like the other answer says, there is a proposal in the works that would make this kind of loop possible to write. (I am told it was even meant to be included in C++20, but for whatever reason, it was left out at the last moment.)

The proposal is P1306 , currently named 'Expansion Statements', and with any luck it should be included in C++23. There is a tracking issue on GitHub ; the committee proceedings, however, are only visible to members.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM