为什么 sizeof... 不能使用这个别名模板?
Why doesn't sizeof... work with this alias template?
我想将可变参数函数限制为一定数量的输入 - 比如两个。为此,这在我的环境中运行良好(VS2017,C++17):
#include <type_traits>
template<typename... T>
auto f(T...) -> typename std::enable_if<sizeof...(T) == 2>::type {
// no-op
}
int main() {
// f(1); // should fail
f(1,2);
// f(1,2,3); // should fail
}
但是如果我引入别名模板,它不会。
#include <type_traits>
template<typename... T>
using two_params = typename std::enable_if<sizeof...(T) == 2>::type;
template<typename... T>
auto f(T...) -> two_params<T...> { // failed to specialize alias template
}
int main() {
// f(1); // should fail
f(1,2);
// f(1,2,3); // should fail
}
有趣的是,如果我将条件更改为1
或实际需要的输入数量,则替换成功。
// This works, except that it permits a single argument even when it shouldn't.
// Both conditions ||'d together seems to be needed in the general case.
template<typename... T>
using two_params = typename std::enable_if<sizeof...(T) == 1 || sizeof...(T) == 2>::type;
好像f(1,2)
生成了两个sizeof...(T)
的值。这到底是怎么回事?
我看过的一些参考文献:
Microsoft 的 Jonathan Emmett 刚刚 confirmed 说这是一个编译器错误:
Thanks for this report. I can confirm that this is a compiler bug with
alias templates and pack expansions. We are currently working on a
major set of fixes for alias specializations, and this work is
currently slated to be included in the VS 2017 15.9 release. I can
also confirm that this bug is fixed as part of this rework.
我想将可变参数函数限制为一定数量的输入 - 比如两个。为此,这在我的环境中运行良好(VS2017,C++17):
#include <type_traits>
template<typename... T>
auto f(T...) -> typename std::enable_if<sizeof...(T) == 2>::type {
// no-op
}
int main() {
// f(1); // should fail
f(1,2);
// f(1,2,3); // should fail
}
但是如果我引入别名模板,它不会。
#include <type_traits>
template<typename... T>
using two_params = typename std::enable_if<sizeof...(T) == 2>::type;
template<typename... T>
auto f(T...) -> two_params<T...> { // failed to specialize alias template
}
int main() {
// f(1); // should fail
f(1,2);
// f(1,2,3); // should fail
}
有趣的是,如果我将条件更改为1
或实际需要的输入数量,则替换成功。
// This works, except that it permits a single argument even when it shouldn't.
// Both conditions ||'d together seems to be needed in the general case.
template<typename... T>
using two_params = typename std::enable_if<sizeof...(T) == 1 || sizeof...(T) == 2>::type;
好像f(1,2)
生成了两个sizeof...(T)
的值。这到底是怎么回事?
我看过的一些参考文献:
Microsoft 的 Jonathan Emmett 刚刚 confirmed 说这是一个编译器错误:
Thanks for this report. I can confirm that this is a compiler bug with alias templates and pack expansions. We are currently working on a major set of fixes for alias specializations, and this work is currently slated to be included in the VS 2017 15.9 release. I can also confirm that this bug is fixed as part of this rework.