Здравствуйте есть следующий класс, со следующей реализацией:
template<typename Type>
class List : public Memory::INonCopyable
{
struct Node
{
Type value;
Node* next;
Node* prev;
};
public:
explicit List(std::uint8_t countVirtualPages = 1) noexcept
: mAllocator(countVirtualPages, sizeof(Node)) {}
template<typename... Arguments>
void emplaceFront(Arguments&&... arguments) noexcept;
...
private:
std::size_t mSize = 0;
Node* mHead = nullptr;
Node* mTail = nullptr;
Memory::Allocators::PoolAllocator mAllocator;
};
template<typename Type>
template<typename... Arguments>
void List<Type>::emplaceFront(Arguments&&... arguments) noexcept
{
void* memoryForNode = mAllocator.allocate(sizeof(Node));
Node* newNode = new (memoryForNode) Node((std::forward<Arguments>(arguments)...), mHead, nullptr);
if (isEmpty())
{
mHead = mTail = newNode;
}
else
{
mHead->prev = newNode;
mHead = newNode;
}
}
При использовании функции emplaceFront получаю следующие ошибки:
Error C2760 syntax error: unexpected token '...', expected ')'
Error C3520 'arguments': parameter pack must be expanded in this context
Error C2059 syntax error: '...'
Как можно решить эту проблему?
В Вашем случае достаточно поменять скобочки на фигурные:
Node{{std::forward<Arguments>(arguments)...}, mHead, nullptr}
Разберем на более простом примере что же у Вас не так.
#include <utility>
template<typename T>
struct Node
{
T value;
void * unused;
};
template<typename T, typename ... Args>
void f(Args && ... args)
{
delete new Node<T>((std::forward<Args>(args)...), nullptr);
}
struct First
{
First(int, int, int) {}
int m1;
int m2;
int m3;
};
int main()
{
f<First>(1, 2, 3);
}
При передаче в функцию f<First>
трех параметров получается примерно следующий код создания объекта Node<First>
:
//int_* - параметры функции после распаковки пакета параметров
//std::forward опущен, т.к. в данном случае он не столь важен и не играет роли.
Node<First>((int_1, int_2, int_3), nullptr);
синтаксис с круглыми скобками при создании объекта приводит к вызову конструктора с заданным набором параметров, но в Node
нет конструктора с параметрами.
В то же время Node
является агрегатом и объекты этого типа можно инициализировать с помощью "списочной инициализации":
Node<First>{(int_1, int_2, int_3), nullptr};
Далее посмотрим на скобки с параметрами int_*
, которые должны были бы инициализировать подъобъект First
. В данном случае это не список параметров, а всего лишь скобки с операторами "запятая" и операндами оного. Для создания объекта нужно указать тип создаваемого объекта, например, так:
Node<T>{T(int_1, int_2, int_3), nullptr};
Это приведет к вызову конструктора типа T
с тремя параметрами.
Но, если в нашем примере у типа First
убрать конструктор, то код снова откажется компилироваться, т.к. отсутствует подходящий конструктор. Однако, объект типа First
возможно инициализировать с помощью всё той же списочной инициализации, т.е. так:
Node<T>{{int_1, int_2, int_3}, nullptr};
Вернем назад std::forward
с пакетом параметров. Получим такой шаблон:
template<typename T, typename ... Args>
void f(Args && ... args)
{
delete new Node<T>{{std::forward<Args>(args)...}, nullptr};
}
То есть теперь данный код может работать не только с типами, имеющими необходимые конструкторы, но и с типами, которые можно инициализировать с помощью list-initialization
.
Виртуальный выделенный сервер (VDS) становится отличным выбором
В общем, такая задача: Сделать окно и поместить в него некоторую невидимую область и сделать так, чтобы при приближении к этой области курсора...
Теперь, нужно объявить переменную b такого типа, который является специализацией a(В данном случае int, а если бы было A< double > a, то b должна была...