C++ инициализация класса с использованием конструктора шаблона, скомпилированного как объявление функции

Мой пользовательский контейнерный класс не может вызывать конструктор при использовании прямой инициализации.

Вот мой код

#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());
}

На главную звоню C<const A&> c(Awrap(a)); и это скомпилировано как объявление типа функции C<const A&> (&)(Awrap), Тем не менее, если я обернуть параметр для конструктора с круглыми скобками, как C<const A&> c((Awrap(a))); это скомпилировано как инициализация.

Вопрос

  1. Я не могу понять, как параметр переноса имеет значение.

  2. Также я не знаю, почему первый скомпилирован как объявление функции. Можно ли объявить функцию без явного упоминания типа и указать тип параметра как объект без компиляции?

0 ответов

Другие вопросы по тегам