I am surprised that the following code produces an error:
#include <cstddef> template<typename T, T... Is> struct Bar { }; template<size_t... Is> using Baz = Bar<size_t, Is...>; struct Foo { // the following two lines give error: // no instance of constructor "Foo::Foo" matches the argument list Foo() : Foo(Baz<4, 2>()) { } // delegating ctor using an alias Foo(int) : Foo(Bar<size_t, 4, 2>()) { } // delagating ctor template<size_t... Is> Foo(Baz<Is...>) { } // however, the overload below which doesn't use the Baz alias works fine // template<size_t... Is> // Foo(Bar<size_t, Is...>) { } template<size_t... Is> void NoAlias(Bar<size_t, Is...>) { } template<size_t... Is> void Alias(Baz<Is...>) { } }; template<typename T, T... Is> void foo(Bar<T, Is...>) { } template<size_t... Is> void bar(Bar<size_t, Is...>) { } int main(int argc, char* argv[]) { // In addition, all of these work fine foo(Bar<size_t, 4, 2>()); foo(Baz<4, 2>()); bar(Bar<size_t, 4, 2>()); bar(Baz<4, 2>()); Foo direct_noalias((Bar<size_t, 4, 2>())); Foo direct_alias((Baz<4, 2>())); direct_alias.NoAlias(Bar<size_t, 4, 2>()); direct_alias.NoAlias(Baz<4, 2>()); // However, these four give error, even though the constructor call chain // mimics the bar(Baz<4, 2>()) / bar(Bar<size_t, 4, 2>()) call Foo delegating_noalias(42); Foo delegating_alias; // and the only difference in NoAlias and Alias is (not) using the alias // for the member function parameter direct_alias.Alias(Bar<size_t, 4, 2>()); direct_alias.Alias(Baz<4, 2>()); return 0; }
For the record, it compiles fine under both GCC 4.8 and Clang 3.4.2.
I discovered this issue by accident while implementing compile-time integer sequence according to the C++14 draft:
http://www.open-std.org/JTC1/sc22/WG21/docs/papers/2013/n3658.html
so it will manifest more in the future as people do more template metaprogramming involving integer sequences. (For example, the index_sequence alias would be unusable in member functions or constructors arguments.)