В C++ путают оператор приведения и вариативный конструктор

C++ (, точнее, реализация MinGW g++ )запуталась. У меня есть математический класс Vector, который содержит произвольное количество элементов произвольного типа. Тип элемента и количество элементов указываются во время компиляции.

Класс Vector путается между одним из своих конструкторов и тем, что я назвал оператором «изменения размера». Оператор изменения размера позволяет программисту преобразовать вектор одного размера в вектор другого произвольного размера. Если вектор приведения содержит больше элементов, чем базовый вектор, он дополняется единицами. Вот реализация:

/*
 * resize operator:
 * T is the type of element the base vector holds
 * N is the number of elements the base vector holds
 * rN is the size of the new vector
 */
template
operator Vector() const 
{
    Vector resize;

    for (unsigned int i = 0; i < rN; i++)
    {
        resize[i] = i < N ? this->elements[i] : 1;
    }

    return resize;
}

Класс вектора также имеет тип -безопасный вариативный конструктор, который может принимать любое количество любых комбинаций элементов (, которые должны быть типа T ), и любое количество векторов (, которые могут содержать любое количество элементов. и должен быть типа T ), если количество пустых элементов, добавленных к количеству элементов в предоставленных векторах, равно количеству элементов, которые содержит конструирующий вектор.

Таким образом, это было бы справедливо:

vec3 foo(vec2(1, 2), 3);

но не это.

vec3 bar(vec4(1, 2, 3, 4), 5);

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

vec4 bar(1, 2, 3, 4);
(vec3) bar; //PROBLEM HERE

Происходит следующее: C++ думает, что (vec3 )bar запрашивает конструктор с переменным числом аргументов, хотя на самом деле он должен вызывать оператор изменения размера. Я пытался сделать их явными, но это не сработало.Как убедиться, что C++ использует оператор изменения размера, когда у меня есть приведенный выше код, а не вариативный конструктор?

Короче говоря, как мне указать C++ использовать это:

//resize operator
template
Vector::operator Vector();

вместо этого:

//constructor
template
Vector::Vector(Args... arguments);

когда у меня есть этот код:

(vec3) someVec4;

Если непонятно, vec3 и vec4 определены как таковые:

typedef Vector vec3;
typedef Vector vec4;

РЕДАКТИРОВАТЬ:

Новости, всем! Даже когда я использую static _cast (someVec4 ), он все равно вызывает конструктор vec3 с аргументом vec4. Я не знаю почему.

ДРУГОЕ РЕДАКТИРОВАНИЕ:

Создание явного конструктора позволяет работать неявным приведениям, но не явным. То есть этот код работает:

vec3 foo = someVec4;

Но этот код по-прежнему выдает ошибку статического утверждения :

vec3 foo = static_cast(someVec4);

. Что в принципе не имеет смысла, потому что я объявил вариативный конструктор явным, и поэтому его не следует вызывать там.

Также, по запросу, вот SSCCE

Версия TL; DR заключается в том, что мой код вызывает явный конструктор, когда я пытаюсь явно вызвать оператор приведения типов, но не когда я пытаюсь вызвать его неявно.

7
задан Avi 11 August 2012 в 13:28
поделиться