为什么此代码不会导致重定义错误?
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>) {}
T
在 non-deduced context 中。因此,由于 SFINAE,此构造函数将始终被拒绝。
请注意您的代码与
有何不同
template<class T>
struct Foo {
Foo(std::initializer_list<T>);
Foo(std::initializer_list<typename T::BarAlias>);
};
Foo<Bar> foo{Bar{}};
确实会产生您预期的错误。
#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>) {}
T
在 non-deduced context 中。因此,由于 SFINAE,此构造函数将始终被拒绝。
请注意您的代码与
有何不同template<class T>
struct Foo {
Foo(std::initializer_list<T>);
Foo(std::initializer_list<typename T::BarAlias>);
};
Foo<Bar> foo{Bar{}};
确实会产生您预期的错误。