编译器正在尝试从int初始化enum类

时间:2016-11-08 14:38:58

标签: c++ enums

我有一个enum类的类型,想要一个" to_string"用于输出类型名称的函数,所以我在我自己的命名空间中编写了它。问题是,该命名空间中的其他函数试图调用to_string,例如,一个int(实际上只是一个int,不打算成为枚举的一部分)是找到自定义的to_string并给出有关枚举无效初始化的错误。

我知道我可以显式调用std :: to_string而不是to_string,但我认为这是更好的方法。我做错了什么?

Here是示例代码:

#include <iostream>
#include <string>

namespace other {
    enum class Type {
        Type1,
        Type2
    };

    std::string to_string(const Type& type) {
        switch(type) {
            case Type::Type1:
                return "Type1";
                break;
            case Type::Type2:
                return "Type2";
                break;
            default:
            {}
        }

        return "Unknown";
    }

    void run() {
        using namespace std;
        cout << string("Type: ") + to_string(Type::Type1) << endl;
        cout << string("int: " )  + to_string(42) << endl;  // this one generates compile-time errors
    }
}

int main() {
    other::run();

    using namespace std;
    cout << string("int: " )  + to_string(42) << endl;  // This one is ok

    return 0;
}

2 个答案:

答案 0 :(得分:4)

您需要明确指定要将哪些功能引入&#34;重载集&#34; see wandbox example

<cassandra-driver.version>3.0.3</cassandra-driver.version>

原因是ADL忽略了使用指令。请参阅 3.4.2 [basic.lookup.argdep]

  

在考虑关联的命名空间时,查找与关联命名空间用作限定符时执行的查找相同(3.4.3.2),但以下情况除外:    - 忽略关联命名空间中的任何using-directive。

更详细的信息in this question

答案 1 :(得分:3)

这是一个棘手的情况,涉及名称空间的一些细微规则。让我们考虑一个更简单的例子:

namespace b {
  void f(int) { }
}

namespace a {
  using namespace b;

  void f(char) { }

  void g()
  {
    f(5); // calls f(char)
  }
}

这里的问题是,即使我们有using namespace b,b中的声明也会被视为在公共命名空间(全局)中为了查找而被声明:

(C ++ 14 7.3.4 / 2)

  

using-directive指定指定命名空间中的名称可以在其中使用的范围内   using-directive出现在using-directive之后。在非限定名称查找(3.4.1)期间,将显示名称   好像它们是在最近的封闭命名空间中声明的,它包含using-directive和   提名命名空间。 [注意:在此上下文中,“包含”表示“直接或间接包含”。 - 结束   注意]

因此,出于查找的目的,名称空间b中的名称被视为它们在全局名称空间中。这意味着命名空间a中的f(char)将在命名空间b中隐藏f(int)

(C ++ 14 3.3.10 / 4)

  

在查找由命名空间名称限定的名称期间,否则将进行声明   using-directive 可以在包含的名称空间中使用相同名称的声明隐藏   使用指令;见(3.4.3.2)。

在您的示例中,to_string(42)中对other::run()的调用会找到other::to_string,因为隐藏了std::to_string(int)