这个荒谬的代码在 Clang 和 GCC 中编译得很好吗?
Is this absurd code that compiles fine a bug in both Clang and GCC?
我今天在玩模板,看看我是否可以让编译器从它的一个内部类中推断出外部类的类型。我没有找到我的解决方案(我怀疑这是不可能的(,但是在尝试修复错误时,我遇到了非常奇怪的行为,我将其简化为以下代码片段。
struct A
{
struct B{};
template <typename T>
struct EverythingIsFine
{
using Outer = T;
using Inner = typename T::B::B::B::B::B::B;
};
using ItWillBeOkay = EverythingIsFine<B>; // Probably not ok
using InnerProblem = ItWillBeOkay::Inner; // Still not ok
using OuterProblem = decltype(B().ItWillBeOkay::Outer::B::B::B
::B::B::B::~B()); // Not even CLOSE to ok
};
令人惊讶的是,它的编译没有警告,也没有Clang和GCC的错误。
我的编译器版本是gcc version 5.3.1 20160121 (Debian 5.3.1-7)
和Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2)
的,用于编译的标志是-std=c++11 -Wall -Wextra
的。
我观察到它在具有 C++14 设置的 Ideone 上也能很好地编译。
然后,我使用这个简单的测试来获得确切的InnerProblem
类型和OuterProblem
:
template <class T> void Type();
int main()
{
Type<A::InnerProblem>();
Type<A::OuterProblem>();
}
两个编译器在编译测试时报告相同的类型:
在函数
main
中:
主.cpp:20:未定义对void Type<A::B>()
的引用 主.cpp:21:未定义对void Type<void>()
的引用
也就是说,InnerProblem
的类型是A::B
的,OuterProblem
的类型是void
的。
这是标准以某种方式允许的还是两个编译器中的错误?
既然我似乎和我的编译器一样困惑,那么这段代码到底发生了什么?
编辑:作为一个简化的后续,因为我不明白为什么两个编译器不能给出相同的结果,下面的代码使用 Clang 编译,但不使用 GCC 编译。
struct A
{
struct B{};
template <typename T>
struct EverythingIsFine
{
using Inner = typename T::B::B::B;
};
using Problem = EverythingIsFine<B>::Inner::B::B::B; // Not ok
};
GCC 现在输出以下错误:
main.cpp:11:26: 错误:"A::B::B"命名构造函数,而不是类型 使用 InnerProblem = EverythingIsFine::Inner::B::B::B;不行
有效的。
类名也入到类本身的作用域中; 这称为注入类名。(9/2(。
所以B::B
命名类B
,B::B::B
也是如此,等等。
编辑:
所以typename B::B
把类命名为B
,typename B::B::B
也是如此,依此类推。
- 我编写了代码将十进制分数转换为其二进制等效数.它编译得很好,但在执行时挂起
- Red Hat:使用<atomic>编译很好,但链接器找不到__atomic_store_16;什么库?
- 如果我的源文件中使用常数,则如何使编译很好地停止
- 为什么"int & const" MSVC 编译得很好?
- 用"gcc -c"通关很好地编译一个C++程序。为什么?
- C++,如果其他新文件出现问题,使用g++进行编译可以很好地工作
- C++:这个代码有什么问题吗?它编译得很好,但人们告诉我会有内存泄漏
- 这个荒谬的代码在 Clang 和 GCC 中编译得很好吗?
- 当我为调试Lua编译程序时,运行得很好,但为什么我要为发布版编译它,我得到了一个c0000005错误
- cpp文件不使用cl编译,但在Visual Studio中编译得很好
- 为什么这个模板 constexpr 函数不能在 gcc 上编译,但在 clang 上效果很好?
- C++计算器程序正在跳过if语句,即使它编译得很好
- 为什么' int; '在C语言中可以很好地编译,但在c++中却不能
- 强制转换操作符函数在g++中可以很好地编译,但在其他编译器中不行.为什么
- 为什么很少有人输入常量正确的代码?将const-correct代码编译更好/更快
- 很好地要求(不是编译时强制)子类创建者做某些事情
- 在 Cygwin 中编译:'EOF'没有在此范围内声明,在 CentOS 中编译得很好
- 为什么这个格式错误的程序在 g++ 中编译得很好
- 代码在Visual Studio中可以很好地编译,但在使用g++的Unix终端中就不行了.我在多维向量处得到一个错误.为
- c++在Eclipse CDT中编译我的代码工作得很好,但是从命令行执行会导致大量错误