3

I want to limit a variadic function to a certain number of inputs - say, two. For that, this works fine in my environment (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
}

But if I introduce an alias template, it doesn't.

#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
}

Interestingly, if I change the condition to 1 or the actual desired number of inputs, the substitution is successful.

// 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; 

It seems that f(1,2) generates two values of sizeof...(T). What exactly is going on here?

Some references I've looked at:

llf
  • 610
  • 10
  • 11
  • @hvd the first code block, but instead using the alias-template-using version of `f` (`auto f(T...) -> two_params`). – llf Jul 14 '18 at 08:06
  • @hvd I have made the second code block a MWE for compile failure. It seems that it compiles in gcc & clang but not MSVC. – llf Jul 14 '18 at 08:13
  • You're right, I messed up when testing. –  Jul 14 '18 at 13:40
  • @lightningleaf Your second code block (using the alias of `enable_if` works fine for me. Maybe I am mistaken? – L. F. Jul 14 '18 at 13:58
  • 1
    @L.F. It work fine for me. CLang on darwin. Maybe a bug of VS2017 – martian Jul 14 '18 at 17:00

1 Answers1

1

Jonathan Emmett from Microsoft has just confirmed that it's a compiler bug:

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.

Evg
  • 25,259
  • 5
  • 41
  • 83