Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is substitution performed on a variadic parameter pack type if the pack is empty?

Consider the following program:

#include <type_traits>

enum class dummy {};
template <typename T>
using EnableIf = typename std::enable_if<T::value, dummy>::type;
template <typename T>
using DisableIf = typename std::enable_if<!T::value, dummy>::type;

template <typename T>
struct dependent_true_type : std::true_type {};

template <typename T,
          EnableIf<dependent_true_type<T>>...>
std::true_type f();
template <typename T,
          DisableIf<dependent_true_type<T>>...>
std::false_type f();

static_assert(decltype(f<int>())::value, "");

int main() {}

GCC 4.7 glady accepts this program. My recent clang 3.1 build claims the call to f is ambiguous.

test.c++:22:24: fatal error: call to 'f' is ambiguous
static_assert(decltype(f<int>())::value, "");
                       ^~~~~~
test.c++:17:16: note: candidate function [with T = int, $1 = <>]
std::true_type f();
               ^
test.c++:20:17: note: candidate function [with T = int, $1 = <>]
std::false_type f();
                ^
1 error generated.

It does accept the program if I write f<int, dummy{}>().

It seems clang does not consider the type of the parameter pack when the pack is empty, which leads to not removing it from the candidate set. GCC seems to perform substitution on the parameter pack type even if the pack is empty, and since said substitution fails for one overload, there is no ambiguity.

Which of the two is correct?

like image 587
R. Martinho Fernandes Avatar asked Apr 30 '12 00:04

R. Martinho Fernandes


People also ask

What is parameter pack in c++?

Parameter packs (C++11) A parameter pack can be a type of parameter for templates. Unlike previous parameters, which can only bind to a single argument, a parameter pack can pack multiple parameters into a single parameter by placing an ellipsis to the left of the parameter name.

What is the use of Variadic templates?

Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration. However, variadic templates help to overcome this issue.


1 Answers

I believe I have found the relevant piece of standardese. §14.8.2p7 says:

The substitution occurs in all types and expressions that are used in the function type and in template parameter declarations.

Since EnableIf<dependent_true_type<T>> is used in a template parameter declaration, substitution should occur and this is a bug in clang.

like image 171
R. Martinho Fernandes Avatar answered Oct 12 '22 20:10

R. Martinho Fernandes