【发布时间】:2015-06-20 15:34:15
【问题描述】:
直接使用默认参数值生成整数序列如下导致硬错误(编译器clang-3.6):
#include <iostream>
#include <utility>
#include <cstdlib>
template< std::size_t M, std::size_t N > // say M - arity, N - number of types
struct test
{
template< std::size_t ...i >
void
operator () (std::index_sequence< i... > = std::make_index_sequence< M >{}) const
{
std::size_t indices[M];
for (std::size_t & m : indices) {
m = 0;
}
for (;;) {
(std::cout << ... << indices[i]) << std::endl;
std::size_t m = 0;
for (;;) {
std::size_t & n = indices[m];
++n;
if (n != N) {
break;
}
n = 0;
if (++m == M) {
return;
}
}
}
}
};
int
main()
{
#if 0
test< 3, 3 >{}(); // hard error
#else
test< 3, 3 >{}(std::make_index_sequence< 3 >{}); // ugly workaround
#endif
return EXIT_SUCCESS;
}
看起来很奇怪,因为简单的替换按预期工作。
为什么会这样?为什么在上述情况下无法分配默认参数,但显式分配有效?
将const & 或&& 附加到参数类型没有任何作用。
【问题讨论】:
-
@LightnessRacesinOrbit coliru.stacked-crooked.com/a/14a759868ea02e34
-
似乎期望类型完全等价。
std::make_index_sequence< M >::operator std::index_sequence< i... > () const将是非常有用的功能。 -
@LightnessRacesinOrbit 虽然使用
struct I { constexpr operator std::index_sequence< 0, 1, 2 > () const { return {}; } };的实例作为默认值没有意义。 coliru.stacked-crooked.com/a/6029f0ba22cde57b -
您在没有参数的情况下调用
operator()(),因此i...被推断为一个空包。您现在需要进行从index_sequence<0, ..., M-1>到index_sequence<>的转换,除非M为 0,否则这是不可能的。 -
@0x499602D2 有趣的解释,但从 clang 的错误描述中并不明显。谢谢。
标签: c++ c++11 default-value c++14