Сегодня я нашел следующий интересный код:
SomeFunction(some_bool_variable ? 12.f, 50.f : 50.f, 12.f)
Я создал небольшой образец для воспроизведения поведения:
class Vector3f
{
public:
Vector3f(float val)
{
std::cout << "vector constructor: " << val << '\n';
}
};
void SetSize(Vector3f v)
{
std::cout << "SetSize single param\n";
}
void SetSize(float w, float h, float d=0)
{
std::cout << "SetSize multi param: " << w << ", " << h << ", " << d << '\n';
}
int main()
{
SetSize(true ? 12.f, 50.f : 50.f, 12.f);
SetSize(false ? 12.f, 50.f : 50.f, 12.f);
}
Результатом, который я получаю от запуска вышеуказанного кода, является:
clang++ -std=c++14 -O2 -Wall -pedantic -lboost_system -lboost_filesystem -pthread main.cpp && ./a.out
main.cpp:29:20: warning: expression result unused [-Wunused-value]
SetSize(true ? 12.f, 50.f : 50.f, 12.f);
^~~~
main.cpp:30:21: warning: expression result unused [-Wunused-value]
SetSize(false ? 12.f, 50.f : 50.f, 12.f);
^~~~
2 warnings generated.
SetSize multi param: 50, 12, 0
SetSize multi param: 50, 12, 0
В обоих случаях я ожидал, что один параметр будет передан в SetSize(float)
. Однако передаются два параметра, которые я нахожу крайне запутанными (особенно, поскольку тройной имеет приоритет над запятой, поэтому я предположил, что запятая не ограничивает аргументы функции в этом случае). Например, если используется true
, троянец должен иметь значение 12.f, 50.f
. В этом выражении значение слева от запятой отбрасывается/игнорируется, поэтому я ожидаю, что конечным результатом будет:
SetSize(50.f);
Вторая часть путаницы заключается в том, что мы используем в ternary true
или false
, те же 2 значения передаются функции. Случай true
должен быть h=12, w=50
Я бы подумал...
Я вижу, что компилятор пытается предупредить меня о чем-то, но я не могу понять, что происходит. Может ли кто-то разложить эту логику и объяснить результат шаг за шагом?