std::index_sequence_for作为默认参数的问题?

以下 C++20 程序:

#include <utility>
#include <cstddef>

template<typename... Args>
class C {
    template<size_t... I>
    static void call(
      std::index_sequence<I...> = std::index_sequence_for<Args...>{}
    ) {}
};

int main() {
    C<long int>::call();
}

无法编译并显示错误消息:

test.cc: In static member function ‘static void C<Args>::call(std::index_sequence<I ...>) [with long unsigned int ...I = {}; Args = {long int}; std::index_sequence<I ...> = std::integer_sequence<long unsigned int>]’:
test.cc:11:20: error: could not convert ‘std::index_sequence_for<long int>{}’ from ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’ to ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’
   11 |  C<long int>::call();
      |                    ^
      |                    |
      |                    integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>
test.cc:11:20: note:   when instantiating default argument for call to ‘static void C<Args>::call(std::index_sequence<I ...>) [with long unsigned int ...I = {}; Args = {long int}; std::index_sequence<I ...> = std::integer_sequence<long unsigned int>]’
test.cc: In function ‘int main()’:
test.cc:11:20: error: could not convert ‘std::index_sequence_for<long int>{}’ from ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’ to ‘integer_sequence<[...],#‘nontype_argument_pack’ not supported by dump_expr#<expression error>>’

有任何想法吗?

更新:

我目前最好的解决方法是将默认参数分解为两个函数,例如:

template<typename... Args>
class C {
    static void call() {
      _call(std::index_sequence_for<Args...>{});
    }

    template<size_t... I>
    static void _call(std::index_sequence<I...>) {}
};

这似乎可以解决编译器错误(如果是这样的话)。

更新 2:

以下程序失败的原因与原始程序相同:

template<typename T> void f(T x = 42) {}

int main() { f(); }

所以这是一个功能而不是一个错误。

回答

一般来说模板参数推导+默认函数参数会造成很多麻烦。要简单地修复它,您可以使用以下方法:

#include <utility>
#include <cstddef>

template<typename... Args>
class C {
public:
    static void call() {
        call_impl(std::index_sequence_for<Args...>{});
    }

private:
    template<size_t... I>
    static void call_impl(std::index_sequence<I...> ) {
    }
};

int main() {
    C<long int>::call();
}


以上是std::index_sequence_for作为默认参数的问题?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>