Как добиться GLSL vec * конструирования синтаксиса без умного компилятора в C ++? - PullRequest
0 голосов
/ 29 августа 2018

В GLSL , мы можем сделать это

vec4 v = vec4(vec3(10.f, 20.f, 30.f), 1.f);

Итак, я попытался сделать это в C ++

struct vec3
{
    float x, y, z;
    vec3(){}
    vec3(float all) : x(all), y(all), z(all) {}
    vec3(float a, float b, float c) : x(a), y(b), z(c){}
};

struct vec4
{
    float x, y, z, w;
    vec4() {}
    vec4(float all) : x(all), y(all), z(all), w(all) {}
    vec4(float a, float b, float c, float d) : x(a), y(b), z(c), w(d) {}
    // Here is the trick
    vec4(vec3 v3, float d) : x(v3.x), y(v3.y), z(v3.z), w(d) {}
};

Это работает, но проблема в том, что я могу инициализировать vec4 только с двумя числами с плавающей точкой ... кажется, что компилятор заменяет vec4(a, b); на vec4(vec3(a), b); во время компиляции, что это то, что я не хочу, потому что это сбивает с толку и нежелательно, я бы с большей вероятностью выдал ошибку, но как?

int main()
{
    vec3 V3 = vec3(10.f, 20.f, 30.f);
    vec4 V4;
    // Works
    V4 = vec4(V3, 1.f);
    // This also works which is a problem.
    V4 = vec4(10.f, 1.f); // == vec4(vec3(10.f), 1.f);
}

1 Ответ

0 голосов
/ 29 августа 2018

Одна вещь, которую вы можете сделать, это указать метод deleted в классе vec4:

vec4(float a, float b) = delete;

Тогда, если вы попытаетесь создать vec4 с двумя числами, он просто будет жаловаться на попытку использовать удаленный метод.

a.cpp: в функции int main ():
a.cpp: 27: 24: ошибка: использование удаленной функции ‘vec4 :: vec4 (float, float)’
V4 = vec4 (10.f, 1.f); // == vec4 (vec3 (10.f), 1.f);

Конечно, сообщение об ошибке не самое лучшее, но, по крайней мере, будет ошибка и неявные преобразования.


Другой способ, который дает лучшее сообщение об ошибке, но может изменить функциональность в другом месте, - указать конструктор vec3 как explicit. Это означает, что компилятору не разрешено неявно преобразовывать float в vec3:

explicit vec3(float all) : x(all), y(all), z(all) {}

Это вызывает следующую ошибку:

a.cpp: 26: 24: ошибка: не соответствует функция для вызова call vec4 :: vec4 (float, float) ’
V4 = vec4 (10.f, 1.f); // == vec4 (vec3 (10.f), 1.f);

a.cpp: 16: 5: примечание: кандидат: vec4 :: vec4 (vec3, float) vec4 (vec3 v3, float d): x (v3.x), y (v3.y), z (v3.z), w (d) {} ​​

a.cpp: 16: 5: примечание: неизвестное преобразование для аргумента 1 из «float» в «vec3»

Так что понятно, почему эта ошибка возникает, но если в какой-то момент вы хотели бы иметь неявные преобразования, это, конечно, не допускает этого.

...