Розглянемо цей код:
#include <vector>
#include <iostream>
enum class A
{
X, Y
};
struct Test
{
Test(const std::vector<double>&, const std::vector<int>& = {}, A = A::X)
{ std::cout << "vector overload" << std::endl; }
Test(const std::vector<double>&, int, A = A::X)
{ std::cout << "int overload" << std::endl; }
};
int main()
{
std::vector<double> v;
Test t1(v);
Test t2(v, {}, A::X);
}
Це відбитки:
vector overload
int overload
Чому це не створює помилки компіляції через неоднозначну роздільну здатність перевантаження? Якщо другий конструктор буде видалений, отримуємо vector overload
два рази. Як / за якою метрикою int
однозначно краще відповідати, {}
ніж std::vector<int>
?
Підпис конструктора, безумовно, може бути виправлений далі, але мене просто обдурило еквівалентний фрагмент коду і хочу переконатися, що нічого важливого не втрачено в цьому питанні.
{}
ефективно робить у певних особливих випадках, але це, як правило, не правильно (для початківців, std::vector<int> x = {};
працює, std::vector <int> x = 0;
ні). Це не так просто, як " {}
призначає нуль".
struct A { int x = 5; }; A a = {};
не призначає нуль в жодному сенсі, він будує A
з a.x = 5
. Це не схоже на те A a = { 0 };
, що ініціалізується a.x
на 0. Нуль не притаманний {}
, йому властиво те, як кожен тип будується за замовчуванням або ініціалізується значення. Дивіться тут , тут і тут .
{}
як блок коду, призначає 0 змінним - приклад: const char x = {}; встановлено на 0 (нульовий знак), те саме для int etc.