2015-07-20 2 views
-2

Я ищу для создания «фабричной функции» для математического класса Vector, который является шаблоном для размера и типа. Вот объявление класса:Variadic Templated Factory Function

template<class T, std::size_t n> 
class Vector { 
    std::array<T, n> elements; 

public: 
    Vector(); 
    explicit Vector(std::array<T, n>& elements_); 
    explicit Vector(const Vector<T, n>& v); 
    explicit Vector(Vector<T, n>&& v); 
    ~Vector() noexcept = default; 
    Vector<T, n>& operator =(const Vector<T, n>& v); 
    Vector<T, n>& operator =(Vector<T, n>&& v); 
    T& operator [](std::size_t i); 
}; 

Идея заключается в том, что это раздражает, чтобы сначала создать массив, а затем сделать вектор из него. Я хочу переменную функцию, называемую make_vector, которая принимает аргументы n того же типа T и возвращает вектор этого типа и размера. Вот моя попытка:

template<class T, class... Ts> 
    Vector<T, sizeof...(Ts) + 1> make_vector(T v1, Ts... args) { 
    const std::size_t sz = sizeof...(Ts) + 1; 
    std::array<T, sz> vals = {v1, args...}; 
    return Vector<T, sz>{vals}; 
    } 

Однако, я получаю следующие ошибки: недоумение

In file included from main.cpp:6: 
In file included from ./oglmath.hpp:3: 
In file included from ./vector.hpp:79: 
./vector.tpp:14:31: warning: suggest braces around initialization of subobject 
     [-Wmissing-braces] 
    std::array<T, sz> vals = {v1, args...}; 
           ^~~~~~~~ 
           {  } 
main.cpp:32:17: note: in instantiation of function template specialization 
     'ogl::make_vector<float, float, float>' requested here 
    vertices[0] = make_vector(-1.0f, -1.0f, 0.0f); 
       ^
In file included from main.cpp:6: 
In file included from ./oglmath.hpp:3: 
In file included from ./vector.hpp:79: 
./vector.tpp:15:12: error: no matching constructor for initialization of 'Vector<float, 
     sizeof...(Ts) + 1>' 
    return Vector<T, sz>{vals}; 
      ^~~~~~~~~~~~~~~~~~~ 
./vector.hpp:13:5: note: candidate constructor not viable: requires 0 arguments, but 1 
     was provided 
    Vector(); 
    ^
In file included from main.cpp:6: 
In file included from ./oglmath.hpp:3: 
In file included from ./vector.hpp:79: 
./vector.tpp:42:12: error: non-const lvalue reference to type 'Vector<[2 * ...]>' cannot 
     bind to a temporary of type 'Vector<[2 * ...]>' 
    return Vector<T, n>(v); 
      ^~~~~~~~~~~~~~~ 
main.cpp:32:15: note: in instantiation of member function 'ogl::Vector<float, 
     3>::operator=' requested here 
    vertices[0] = make_vector(-1.0f, -1.0f, 0.0f); 
      ^
1 warning and 2 errors generated. 

В самом деле? Единственный конструктор, который он может найти, тривиальный? Что происходит!? Я полностью ожидал, что это провалится странным образом, если я попытаюсь использовать разные типы в моем Ts, но я был осторожен, чтобы сделать их плавающими! Кроме того, почему он сердится на мою инициализацию моего std::array? Я попробовал добавить браслеты, и он ошибся вместо предупреждения.

+2

Вы имеете в виду 'Vector make_vector (T v, Ts ... args) {', right? Есть и другие подобные опечатки. Кажется, это вопрос опечатки, иначе ваши ошибки будут разными. Отправьте свой _actual_ [testcase] (http://stackoverflow.com/help/mvce), а не что-то с неизвестными номерами несвязанных и незарегистрированных дополнительных ошибок. –

+0

исправил проблему, вызванную @LightnessRacesinOrbit – FizzixNerd

+0

Также добавлены дополнительные 'явные' и' ... args' вместо 'args ...'. С фиксированными фиксированными опечатками, я могу в принципе получить эту работу (по модулю отсутствующих определений ctor): http://coliru.stacked-crooked.com/a/dbe4274c73ab0936 Снова я хочу пояснить, что эти проблемы привели к _полным_ другим сообщениям, чем показано в вашем вопросе (ну кроме одного) –

ответ

2

Мы не можем видеть ваше использование, но мы можем сказать, что в нескольких местах ваши копии-инициализации полагаются на неявное преобразование, где такое преобразование не доступно.

explicit на копии ctor необычен; не думаю, что я когда-либо видел случай, в котором это желательно.

Удалить explicit с копией ctor.

+0

«Явный» экземпляр ctor и неявный move ctor могут быть полезны: он блокирует неявные копии (что может быть дорого), но позволяет это, если вы явно скопируете его, а затем переместите значение в цель (что часто может быть отодвинутым). – Yakk

Смежные вопросы