使用模板构造函数编译为函数声明的C ++类的初始化

时间:2018-12-28 13:41:49

标签: c++ most-vexing-parse

使用直接初始化时,我的自定义容器类无法调用构造函数。

这是我的代码

#include <iostream>
#include <list>

template <class T>
struct C
{
    T t_;

    template <class U,
              class = typename std::enable_if
                    <
                        !std::is_lvalue_reference<U>::value
                    >::type>
        C(U&& u) : t_(std::forward<T>(std::move(u).get())) {}
};

class A
{
    int data_;
public:
    explicit A(int data = 1)
        : data_(data) {}
    ~A() {data_ = -1;}

    void test() const
    {
        if (data_ < 0)
            std::cout << "A is destructed\n";
        else
            std::cout << "A = " << data_ << '\n';
    }
};

class Awrap
{
    const A& a_;
public:
    explicit Awrap(const A& a) : a_(a) {}
    const A& get() const {return a_;}
};

template <class C>
void test(C c)
{
    c.t_.test();
}

int main()
{
    std::list<C<const A&> > list;
    A a(3);
    C<const A&> c(Awrap(a));
    list.push_back(c);
    test(c);
    test(list.front());
}

在Main,我调用C<const A&> c(Awrap(a));并将其编译为函数类型C<const A&> (&)(Awrap)的声明。但是,如果我用括号将C<const A&> c((Awrap(a)));括起来作为构造函数的参数,它将编译为初始化。


  1. 我不明白包装参数如何造成这种差异。

  2. 我也不知道为什么第一个编译为函数声明。是 可以在不显式提及类型的情况下声明函数 并将参数类型指定为非编译时间对象?

0 个答案:

没有答案