首页 > 解决方案 > 关于阴影类型定义的警告

问题描述

情况如下:在代码库中,定义了一些类型的标头,大多数是方便的快捷方式,例如 u64 的 uint64_t 存在。这些定义是全局的,因为通用类型定义在封装在命名空间中时并没有真正意义。几乎所有其他文件都使用此标头来统一代码库。

还使用了一个公共可用的仅标头库,它恰好定义了相同的名称。实际上,另一个定义不是类型,而是参数名称,例如:

void function(uint64_t u64);

现在编译器会抛出有关参数名称会影响全局类型定义的警告。这在某些方面是正确的。

但是由于需要通用的全局类型管理标头并且还需要库的包含,我的问题是如何以理智的方式解决该问题。

此外,为什么类型名称可以被函数参数/参数名称隐藏,因为变量名称和类型名称是两个非常不同的东西。对我来说,这听起来更像是编译器中的一个错误。如果没有对该主题的标准有充分的了解,我会假设

using mytype = unsigned int;
void myfunc(mytype mytype);

是有效的,因为我刚刚定义了一个与类型同名的变量,但编译器总是可以区分两者,因为语法。


附加问题:

为什么两个标题的包含顺序似乎没有效果。

我试图通过首先包含外部库标头来解决问题(因此该模块中不应存在全局类型快捷方式)并包含稍后定义类型的通用全局标头。但是警告仍然存在。


编辑以解决问题(2次)

标签: c++

解决方案


但是由于需要通用的全局类型管理标头并且还需要库的包含,我的问题是如何以理智的方式解决该问题。

您可以做的一件事是隔离使用产生该错误的标头的代码,并将其移动到它自己的编译单元中,您可以在该编译单元中静默该阴影错误消息。

此外,为什么类型名称可以被函数参数/参数名称隐藏,因为变量名称和类型名称是两个非常不同的东西。

它们是两个不同的东西,但在某些情况下两者的语法相同,因此编译器必须决定是使用参数还是使用类型。

这里有一个例子,with static_assert, 可能很奇怪,但也许在其他情况下这实际上很难调试:

#include <utility>

struct Type {
    constexpr bool operator == (int i) {
        return i==102;
    }
};

template <typename X>
constexpr void f1(X Type) {
  // does not fail because lambda is called which returns 101
  static_assert(Type() == 101, "");
}


void f2() {
  // fails because the operator == checks against 102
  static_assert(Type() == 101, "");
}


int main() {
  f1([] { return 101; });
  f2();

  return 0;
}

这可能是一个更好的例子,也许仍然是一个奇怪的例子,但我可以想象这个例子更有可能发生:

bar(TypeA());不会TypeA直接构造,而是TypeA operator ()在类型的对象上调用TypeB

#include <utility>

struct TypeA {
    void operator () () {
    }
};

struct TypeB {
    TypeA operator () () {
        return TypeA();
    }
};


void bar(TypeA a) {
}

void foo(TypeB TypeA ) {
    bar(TypeA());
}

int main() {
    foo(TypeB());
}

推荐阅读