为什么此代码不会导致重定义错误?

Why this code is NOT causing redefinition error?

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

我认为编译器应该在 Foo 中生成两个完全相同的构造函数。为什么它还能工作?

您有两个带有不相关模板参数 T 的模板。对于第二个构造函数作为候选者,T 至少应该是可推导的。然而,在

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

Tnon-deduced context 中。因此,由于 SFINAE,此构造函数将始终被拒绝。

请注意您的代码与

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

Foo<Bar> foo{Bar{}}; 确实会产生您预期的错误。