声明变量C ++,C ++ 11时无效使用auto

时间:2018-06-01 10:24:12

标签: c++ c++11 auto

每当我尝试编译代码时,我都会无效使用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 :(得分:8)

非正式地说,auto可以用于同时声明和初始化类型。然后编译器可以从用于初始化变量的值推断出类型。

但事实并非如此;像

这样的陈述
auto n;

也会失败。

请注意,auto仅代表在编译时已知的类型。在那里使代码更具可读性,尽管它的使用偶尔也是强制性的,例如在使用lambda函数时。 不是变体类型构造cf. std::variant说C ++ 17。

最后请注意,std::mapjava.util.Map是完全不同的野兽。 C ++中没有类型擦除,因此如果std::map<A, B>std::map<C, D>不同,AC的根本不同类型}和/或BD不同。此外,C ++允许您在地图中存储值类型。

答案 1 :(得分:1)

正如其他用户已经说过的那样,没有右手变量,auto就无法工作。

我认为您应该从AnimalRenderer中删除模板注释,然后您可以正常使用这些类。

答案 2 :(得分:1)

要获得您想要的结果,您需要在案例中移动第二个for循环,其中可以针对每种情况解决扣除。

您不希望代码重复,因此理想情况下您需要一个模板函数,您可以调用它来执行第二个循环。在最新的c ++标准中,您也可以声明模板lambda函数。

那就是说,在架构上,我建议为AnimalRenderer添加一个接口基类,然后你可以声明一个指向该基类的简单指针,特别是当你已经将draw声明为虚拟时。