Search code examples
c++templatesc++17constexprconstexpr-function

Compiler can't execute constexpr expression


I have code something like this:

template<typename ... Args>
constexpr size_t get_init_size(Args ... args) {
    return sizeof...(Args);
}

template<typename ... Args>
constexpr auto make_generic_header(Args ... args) {
    constexpr size_t header_lenght = get_init_size(args...);
    return header_lenght;
}

constexpr auto create_ipv4_header() {
    constexpr auto x = make_generic_header(0b01, 0b10, 0b01);
    return x;
}

I know it is dummy code, but I isolate it to find error.

Compiler give me error(GCC):

In instantiation of 'constexpr auto make_generic_header(Args&& ...) [with Args = {int, int, int}]':
/tmp/tmp.CaO5YHcqd8/network.h:39:43:   required from here
/tmp/tmp.CaO5YHcqd8/network.h:31:22: error: 'args#0' is not a constant expression
   31 |     constexpr size_t header_lenght = get_init_size(args...);
      |                      ^~~~~~~~~~~~~

I tried add qualifier const to function parameters but it same doesn't work. In theory all this function can calculate in compile time. But where is problem I can't find with my knowledge.


Solution

  • I rewrite the code that will be work and I think will be execute in compile time:

    template<typename ... Args>
    constexpr auto make_generic_header(const Args ... args) {
        std::integral_constant<size_t, sizeof...(Args)> header_lenght;
        return header_lenght.value;
    }
    
    constexpr auto create_ipv4_header() {
        constexpr auto x = make_generic_header(0b01, 0b10, 0b01);
        return x;
    }
    

    I removed function get_init_size and used code part of template parameter(It is guaranteed that it is will be execute on compile time) and after return the number of arguments passed to function(For std::integral_constant for all object value same and know on compile time)