gpt4 book ai didi

C++ 解决方法 : `invalid initialization of reference of type ‘C*&’ from expression of type ‘B*’

转载 作者:行者123 更新时间:2023-11-30 05:00:23 25 4
gpt4 key购买 nike

最近我第一次发现这个错误:invalid initialization of reference of type ‘C*&’ from expression of type ‘B*’。将代码从 gcc 4.9 移植到 gcc 6 时出现错误。下面我粘贴了一个最小的代码示例。

class A {
public:
A() : a(1) {};
virtual ~A() {};
int a;
};

class B : public A {
public:
B() : val(2) {};
int val;
};

class C : public A {
public:
C() : val(3) {};
float val;
};

int alloc_b(B*& entry) {
try {
entry = new B;
} catch(...) {
return -1;
}
return 0;
}

int alloc_c(C*& entry) {
try {
entry = new C;
} catch(...) {
return -1;
}
return 0;
}

template<typename T>
int whatever(const bool isB) {
T* entry = NULL;
if(isB) {
alloc_b(entry);
} else {
alloc_c(entry);
}

std::cout << entry->val << "\n";
}

int main() {
int rv;
B* ptrB;
C* ptrC;

whatever<B>(true);
whatever<C>(false);
return 0;
}

我知道出现错误是因为在使用 isB = true 编译方法 whatever 时,它还试图编译 alloc_c() 调用,因此它检查 T = B 并且找不到任何 alloc_c(B*& entry) 方法,因此失败。另一种方式从类型“C*”的表达式中对类型“B*&”的引用的初始化无效当使用类型C<调用方法whateverisB = false

我只是想知道解决这个问题的最干净的方法是什么。我发现的唯一解决方案是创建一个方法模板 alloc 并进行一些专门化:

template<typename T>
int alloc(T*& entry) {
static_assert((std::is_same<decltype(entry), B>::value ||
std::is_same<decltype(entry), C>::value),
"Class must be A or B");
}

template<>
int alloc(B*& entry) {
return alloc_b(entry);
}

template<>
int alloc(C*& entry) {
return alloc_c(entry);
}

然后在 whatever 函数中,我将调用该 alloc 而不是其他 alloc。

template<typename T>
int whatever(const bool isB) {
T* entry = NULL;
alloc(entry);

std::cout << entry->val << "\n";
}

但我确信必须有更简洁的方法来解决此错误。

最佳答案

I understand that the error appears because when compiling the method whatever with isB = true it is also trying to compile also the alloc_c() call, so it checks that T = B and can't find any alloc_c(B*& entry) method, so it fails.

您可以通过给这个编译时评估的 isB 来防止这种情况发生:

template<typename T, bool isB>
int whatever();

现在,使用 if constexpr将为您提供所需的功能,而不会过多损害您的代码:

template<typename T, bool isB>
int whatever() {
T* entry = NULL;
if constexpr (isB) {
alloc_b(entry);
} else {
alloc_c(entry);
}

std::cout << entry->val << "\n";
}

whatever<B, true>();
whatever<C, false>();

Live Demo

编辑

没有 if constexpr,SFINAE 仍然可以工作——你只需要做更多的输入:

template<typename T, bool isB>
typename std::enable_if<isB, int>::type whatever() {
T* entry = NULL;
alloc_b(entry);

std::cout << entry->val << "\n";
}

template<typename T, bool isB>
typename std::enable_if<!isB, int>::type whatever() {
T* entry = NULL;
alloc_c(entry);

std::cout << entry->val << "\n";
}

Tested with gcc 6.1.0.

关于C++ 解决方法 : `invalid initialization of reference of type ‘C*&’ from expression of type ‘B*’ ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50839448/

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