Home > Enterprise >  Why this code is NOT causing redefinition error?
Why this code is NOT causing redefinition error?

Time:10-25

#include <initializer_list>

struct Foo
{
    template <typename T>
    Foo(std::initializer_list<T>) {}

    template <typename T>
    Foo(std::initializer_list<typename T::BarAlias>) {}
};

struct Bar
{
    using BarAlias = Bar; 
};

int main()
{
    Foo foo{ Bar{} };
}

I believe that a compiler should produce two exactly the same constructors inside of Foo. Why is it even working?

CodePudding user response:

You have two templates with unrelated template arguments Ts. For the second constructor to be a candidate, T should be deducible, at least. However, in

template <typename T>
Foo(std::initializer_list<typename T::BarAlias>) {}

T is in a non-deduced context. As a result, this constructor will always be rejected thanks to SFINAE.

Note how your code is different from

template<class T>
struct Foo {
    Foo(std::initializer_list<T>);
    Foo(std::initializer_list<typename T::BarAlias>);
};

which for Foo<Bar> foo{Bar{}}; will indeed produce an error that you expect.

  • Related