gpt4 book ai didi

c++ - 处理不完整类型的 const/non-const 模板类型引用时的不同编译结果

转载 作者:行者123 更新时间:2023-12-03 06:54:27 25 4
gpt4 key购买 nike

我写了一些代码如下:

#include <iostream>
using namespace std;

struct A;
struct B;

template <typename T>
struct Base;

struct Visitor {
virtual void Visit(const Base<A> & a);
virtual void Visit(const Base<B> & b);
};

template <typename T>
struct Base {
T val;
virtual void Accept(Visitor& v) {
v.Visit(*this);
}
};

struct A {
int a;
};

void Visitor::Visit(const Base<A> & a) {
cout<<"Base<A> visited"<<endl;
}

void Visitor::Visit(const Base<B> & b) {
cout<<"Base<B> visited"<<endl;
}

int main() {
Visitor v;
Base<A> a;

a.Accept(v);

return 0;
}

使用 g++ 7.5.0/Ubuntu 18.04,它无法编译。 g++ 提示 Base<T>::val类型不完整。

但是如果我删除 Visitor::Visit 参数的常量限定符,然后它可以编译并给出预期的结果(打印“Base visited”)。在这种情况下,const 和非常量引用之间有什么区别?

完整的编译器错误信息:

test.cpp: In instantiation of ‘struct Base<B>’:
test.cpp:20:5: required from ‘void Base<T>::Accept(Visitor&) [with T = A]’
test.cpp:41:13: required from here
test.cpp:18:5: error: ‘Base<T>::val’ has incomplete type
T val;
^~~
test.cpp:5:8: note: forward declaration of ‘struct B’
struct B;
^

更新

感谢@Oblivion 和@j6t。你的回答启发了我。

我更改了我的代码以使其更简洁并减少有关问题的噪音:

struct A;
struct B;

template <typename T>
struct Base;

void func(const Base<A> & a) {
}

void func(const Base<B> & b) {
}

template <typename T>
struct Base {
T value;
};

struct A {};

int main() {
func(Base<A>{});
return 0;
}

它会产生同样的错误。所以我认为关键在于函数重载决议。

这是我的推理:当调用 func(Base<A>{}) 时,编译器需要查找重载候选项。对于 const Base<B>& ,需要考虑隐式转换,因为 const 引用可以绑定(bind)到右值。

所以编译器需要实例化Base<B>看看是否有任何此类转换。因为成员(member)T val;一般Base模板,B必须完整。这就是编译错误的来源。

对于 Base<B>& , 只有 Base<B> 的左值被接受。编译器不需要查找隐式转换,也不需要 Base<B> 的实例化。是需要的。

最佳答案

关于您的情况下标准要求的不完整类型:

3.2 One definition rule [basic.def.odr]

an lvalue-to-rvalue conversion is applied to an lvalue referring to anobject of type T (4.1)

你的函数可以这样调用:

a.Accept(Visitor{});

如果您从函数签名中删除 const,则不会接受此类调用。所以这就是为什么每个标准都需要完整的类型。


如果需要处理不完整的类型,可以使用指针:

  virtual void Visit(const Base<A>* a);
virtual void Visit(const Base<B>* b);

住在 Godbolt

关于c++ - 处理不完整类型的 const/non-const 模板类型引用时的不同编译结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64430479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com