提问人:Johny Siemano Kolano 提问时间:11/18/2023 更新时间:11/18/2023 访问量:55
转发 CRTP 派生类不兼容 MSCV/GCC 中定义的返回类型
Forwarding of return type defined in CRTP derived class incompatibility MSCV/GCC
问:
我遇到了 CRTP(奇怪的重复模板模式)基类中的模板函数问题,该基类在 MSVC 和 GCC 编译器上表现出不同的行为。BaseA 基类包含一个模板成员函数 foo(),该函数应该返回继承类中定义的类型。但是,foo() 的两种不同实现在 MSVC 和 GCC 上产生不同的结果。我见过几个类似的stackoverflow线程,但它们都没有解决我的问题。
检查下面的代码或使用此 goldbold 链接。
// Minimal working example
template <typename T>
class BaseA {
public:
//// Version 1 (not working on MSVC and GCC)
//// it is incomplete type usage so it obviously wont work
//T::value_type foo() const {
// return static_cast<const T*>(this)->foo();
//}
//// Version 2 (working on MSVC, not working on GCC)
//// this in my opinion should work everywhere
//// since type U will be deduced after T from BaseA
//// but unluckly it does only work on MSVC
//// GCC error: invalid use of incomplete type 'class DerivedA'
template <typename U = typename T::value_type>
U foo() const {
return static_cast<const T*>(this)->foo();
}
//// Version 3 (working on MSVC and GCC)
//// will work, but "auto" as interface function return value is unaccepted solution.
//// This is only minimal working example, real program is much bigger and it can lead to
//// many issues in the future.
//auto foo() const {
// return static_cast<const T*>(this)->foo();
//}
};
class DerivedA : BaseA<DerivedA> {
public:
using value_type = int;
value_type foo() const {
return 5;
}
};
template <typename T>
void some_interface_call(const BaseA<T>& a) {
auto value = a.foo();
}
int main() {
BaseA<DerivedA> a;
some_interface_call(a);
return 0;
}
传达这种类型的正确、通用方法是什么?
有没有办法在 GCC 下使用尽可能少的更改?Version 2
答:
3赞
Artyer
11/18/2023
#1
这不起作用,因为在声明成员函数模板时,模板的默认值必须有效。
我所看到的“标准解决方法”是在声明中有一个和使用:typename U = T
U
T
template <typename U = T>
typename U::value_type foo() const {
return static_cast<const T*>(this)->foo();
}
评论
0赞
Johny Siemano Kolano
11/18/2023
我检查了它,它可以在 Linux (GCC) 和 Windows (MSVC) 下工作,我一直使用它 - 但这些天我主要在 Windows 上编程,它一直在那里工作。从来没有这样写过。谢谢!Version 2
template <typename U = T::value_type>
上一个:C 和 Matlab 的指数限制
评论
T
在 CRTP 中不完整,因此不能在声明中使用。T::value_type
template <typename T> struct my_value_type; template <> my_value_type<MyObj> { using type = SomeType; /* but not T::type */ };
Version 2