我尝试使用 C++11/14 的一些新功能,但遇到了一个令人讨厌的事情,即在其定义中对类方法进行类型推导。
场景:
// in header foo.hpp
class MyClass {
T foo();
}
//in source foo.cpp
auto MyClass::foo() {
return ... //something that returns T!
}
对于 T = cl_uint (OpenCL),这不起作用,编译器会输出以下错误消息:
src/device.cpp:9:7: 错误:“auto CL::Device::addressBits() const”的原型(prototype)与“CL::Device”类中的任何内容都不匹配
和
src/device.hpp:31:11:错误:候选者是:cl_uint CL::Device::addressBits() const
这与最新版本的 GCC 和 Clang 的行为相同。 具体示例如下:
// in the .hpp
namespace CL {
class Device : public Object<cl_device_id, cl_device_info, DeviceFunctions> {
public:
Device(cl_device_id id);
cl_uint addressBits() const;
// much more stuff ... (not of interest atm)
}
}
// in the .cpp
namespace CL {
auto Device::addressBits() const {
return getInfo<cl_uint>(CL_DEVICE_ADDRESS_BITS);
}
}
// in object.hpp => inherited by device
namespace CL {
template<typename U, typename InfoIdType, typename Functions>
class Object {
protected:
template<typename T>
T getInfo(InfoIdType info_id) const {
auto error = cl_int{CL_INVALID_VALUE};
auto info = T{};
error = Functions::get_info(m_id, info_id, sizeof(T), &info, nullptr);
return (error == CL_SUCCESS) ? info : T{};
}
}
}
我很清楚这个问题不会导致任何可怕的事情,也不能通过忽略这种情况的类型推导来修复它。 然而,当我尝试采用新的、很酷的 C++11/14 功能时,我想了解为什么它不能像我想象的那样工作。
最佳答案
您可以将所有代码简化为:
struct A {
int func();
};
auto A::func() { return 0; }
这是无效的,使用占位符类型声明的函数必须在所有声明中使用占位符:
[decl.spec.auto]/13:
Redeclarations or specializations of a function or function template with a declared return type that uses a placeholder type shall also use that placeholder, not a deduced type.
关于c++ - 方法定义推导的类型与声明不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26288705/