【问题标题】:Why this code is NOT causing redefinition error?为什么此代码不会导致重新定义错误?
【发布时间】:2021-10-24 16:36:08
【问题描述】:
#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 中生成两个完全相同的构造函数。为什么它甚至可以工作?

【问题讨论】:

  • 你的想法是正确的,无论是构造函数{}
  • 这里是答案SFINAE
  • 我看到了两个不同的构造函数。两者之一(构造函数#2)比另一个更专业,在这种情况下被选中。
  • 如果比较专业的话我想应该选择它。

标签: c++ templates redefinition


【解决方案1】:

您有两个带有不相关模板参数Ts 的模板。对于要成为候选的第二个构造函数,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>);
};

which for Foo&lt;Bar&gt; foo{Bar{}}; 确实会产生您期望的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 2019-09-29
    相关资源
    最近更新 更多