Разрешение перегрузки функции с {} - PullRequest
4 голосов
/ 28 октября 2019

Таким образом, наша библиотека C ++ позволяет пользователям передавать списки значений, обернутые в классы с помощью переменных конструкторов, чтобы можно было проверять длины этих списков во время компиляции. Я пытаюсь добавить некоторые новые функции, добавив новые перегруженные функции. Однако «неправильная» перегрузка вызывается, когда я передаю массив параметров нулевой длины, например {}. Следующий минимальный пример иллюстрирует проблему:

#include <iostream>
#include <vector>

class EmptyList
{
public:
    template<typename... T>
    EmptyList(T&&... vals)
    {
        static_assert(sizeof...(vals) == 0, "Wrong number of values");
    }

    std::vector<double> getValues() const { return {}; }
};

void testVector(int *a, std::vector<double> b)
{
    std::cout << "Vector: A (" << a << ")" << std::endl;
}

void testVector(std::vector<double> a, std::vector<double> b)
{
    std::cout << "Vector: B" << std::endl;
}

void testInitList(int *a, std::initializer_list<double> b)
{
    std::cout << "Init list: A (" << a << ")" << std::endl;
}

void testInitList(std::initializer_list<double> a, std::initializer_list<double> b)
{
    std::cout << "Init list: B" << std::endl;
}

void testEmptyList(int *a, const EmptyList &b)
{
    std::cout << "Empty list: A (" << a << ")" << std::endl;
}

void testEmptyList(const EmptyList &a, const EmptyList &b)
{
    std::cout << "Empty list: B" << std::endl;
}

int main()
{
    testVector({}, {});
    testInitList({}, {});
    testEmptyList({}, {});
}

Вывод:

Vector: A (0)
Init list: B
Empty list: A (0)

Мало того, что поведение перегрузки кажется странным, но, похоже, существует особый случай компилятораза std::initializer_list заставляя его вести себя по-разному как в моем классе, так и std::vector. Есть ли способ обойти это, так что перегрузка функции, принимающая мой класс, выбирается из той, что берет указатель?

1 Ответ

1 голос
/ 28 октября 2019

Есть ли способ обойти эту проблему, чтобы перегрузка функции, принимающая мой класс, была выбрана вместо той, которая берет указатель?

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...