【发布时间】:2017-12-16 16:39:33
【问题描述】:
考虑以下实现编译时间计数器的代码。
#include <iostream>
template<int>
struct Flag { friend constexpr int flag(Flag); };
template<int N>
struct Writer
{
friend constexpr int flag(Flag<N>) { return 0; }
};
template<int N>
constexpr int reader(float, Flag<N>) { return N; }
template<int N, int = flag(Flag<N>{})>
constexpr int reader(int, Flag<N>, int value = reader(0, Flag<N + 1>{}))
{
return value;
}
template<int N = reader(0, Flag<0>{}), int = sizeof(Writer<N>) >
constexpr int next() { return N; }
int main() {
constexpr int a = next();
constexpr int b = next();
constexpr int c = next();
constexpr int d = next();
std::cout << a << b << c << d << '\n'; // 0123
}
对于第二个reader重载,如果我把默认参数放在函数体内,像这样:
template<int N, int = flag(Flag<N>{})>
constexpr int reader(int, Flag<N>)
{
return reader(0, Flag<N + 1>{});
}
那么输出会变成:
0111
为什么会这样?是什么让第二个版本不再工作?
如果重要的话,我使用的是 Visual Studio 2015.2。
【问题讨论】:
-
CWG Issue #2118 将使这个程序在未来变得不正确。有关详细信息,请参阅this question。
-
@Rakete1111 好的,我明白了。但是我还有一个问题,为什么不能省略变量“value”?
标签: c++ c++11 templates metaprogramming