C++ operator-comma/forward 引用代码不编译

标签 c++

以下代码无法编译,除非注释行被取消注释:

template <class T> struct R { static T& r(); };
struct M {
    static char m(M&);
    template <class T> static int m(const T&);
};
template <class T> struct A;
template <class T>
struct B {
    struct U { };
    struct V { M& operator,(U); };
    enum { v = sizeof(M::m((R<V>::r(), R<A<T>*>::r()))) };
};
template <class T> struct A { B<T> y; };
int main()
{
//  A<int>();  // Works if uncommented.
    B<int>();
}

在逗号运算符处,编译器认为它需要 A<int>完整,即使代码只在 A<T>* 中传输.我不明白为什么。它因 clang 和 g++ 而失败。 clang 说

h.cpp:13:36: error: field has incomplete type 'B<int>'
template <class T> struct A { B<T> y; };
                                   ^
h.cpp:11:38: note: in instantiation of template class 'A<int>' requested here
    enum { v = sizeof(M::m((R<V>::r(), R<A<T>*>::r()))) };
                                     ^
h.cpp:17:5: note: in instantiation of template class 'B<int>' requested here
    B<int>();
    ^
h.cpp:8:8: note: definition of 'B<int>' is not complete until the closing '}'
struct B {
       ^
1 error generated.

我现在正坐在调试器中调试编译器 :-) 我认为正在发生的事情是编译器正在使用依赖于参数的查找来查找匹配 operator, s 和指向类的指针的关联类和命名空间包括类本身,因此编译器希望类是完整的。也许吧。

最佳答案

如果将 main 更改为这样,您会收到相同的错误消息:

int main()
{
    // A<int>();  // Works if uncommented.

    auto& x = R<A<int>*>::r();
    B<int>();
}

我要大胆地说,正如你所暗示的那样。提到指向 A<int> 的指针不会导致 A<int> 的模板扩展.

这(对我而言)是有道理的,因为它与提及指向前向声明类型的指针相同 - 您此时不需要完全定义的类型。

也许比我聪明的人可以在标准中找到强制执行此操作的段落。

关于C++ operator-comma/forward 引用代码不编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33247104/

相关文章:

c++ - 一个函数知道它的参数占用多少内存吗?

c++ - 在单个函数调用中发出 Qt HTTP 请求并接收响应

c++ - 如何将填充字节添加到位图?

c++ - 如何避免在 C++ 中将 const_cast 与 std::vector::erase() 一起使用?

C++ : friend function in a template class for operator<<

c++ - C++多线程中如何调用非线程安全的DLL?

c++ - 为什么容器需要const

c++ - Rabin-Karp 字符串匹配不匹配

C++ "simple"具有任意参数和返回值的函数的函数回调

C++ lambda - 捕获成员变量