Неправильное использование auto при объявлении переменной C ++, C ++ 11 - PullRequest
0 голосов
/ 01 июня 2018

Всякий раз, когда я пытаюсь скомпилировать свой код, я получаю недопустимое использование auto.Исходя из Java-фона, я не уверен, что понимаю шаблоны C ++.Кажется, что компилятор может определить тип.Я ограничен C ++ 11.

Ошибка возникает в GeneralRenderer.

Классы животных

class Animal {};

class Dog : public Animal {};

class Cat : public Animal {};

enum AnimalType {
    Dog,
    Cat
};

Классы рендеринга

template<class T>
class AnimalRenderer {
    virtual void draw(T entity) = 0;
};

class DogRenderer : public AnimalRenderer<Dog> {};


class CatRenderer : public AnimalRenderer<Cat> {};

Логика

class GeneralRenderer {
public:
    void draw(
            std::map<AnimalType, std::vector<Animal>> animalMap) {

        for (auto entry: animalMap) { 
            AnimalRenderer<auto> renderer; // <--- Causes the error
            switch (entry.first) {
                case Dog:
                    renderer = DogRenderer();
                    break;
                case Cat:
                    renderer = CatRenderer();
                    break;
            }

            for (auto animal: entry.second) {
                renderer.draw(entry);
            }
        }
    };
};

Ответы [ 3 ]

0 голосов
/ 01 июня 2018

Как уже говорят другие пользователи, auto не может работать без правой переменной.

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

0 голосов
/ 01 июня 2018

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

Вам не нужно дублирование кода, поэтому в идеале вам нужна функция шаблона, которую можно вызвать для выполнения второго цикла.В последних стандартах c ++ вы также можете объявить лямбда-функцию шаблона.

Тем не менее, архитектурно, я бы предложил добавить базовый класс интерфейса для AnimalRenderer, а затем вы можете объявить простой указатель на этот базовый класс, особенно если вы уже объявили draw виртуальным.

0 голосов
/ 01 июня 2018

Неформально говоря, auto может использоваться для объявления и инициализации типа одновременно.Затем компилятор может вывести тип из значения, использованного для инициализации переменной.

Но это не тот случай;оператор, подобный

auto n;

, аналогичным образом потерпит неудачу.

Обратите внимание, что auto просто заменяет тип, который известен во время компиляции .Это делается для того, чтобы сделать код более читабельным, хотя его использование иногда обязательно, например, при работе с лямбда-функциями.Это , а не конструкция типа варианта ср.std::variant скажем, C ++ 17.

Наконец, обратите внимание, что std::map - это совсем не то, что зверь * java.util.Map.В C ++ нет типа стирания , поэтому std::map<A, B> принципиально отличается от std::map<C, D>, если A отличается от C и / или B отличается от D,Кроме того, C ++ позволяет хранить типы значений в картах.

...