我尝试使用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'的原型与类'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功能时,我想了解为什么这个特别不能像我想象的那样工作。
答案 0 :(得分:5)
您可以将所有代码简化为:
struct A {
int func();
};
auto A::func() { return 0; }
这是无效的,使用占位符类型声明的函数必须在所有声明中使用占位符:
[decl.spec.auto] / 13:
具有使用占位符类型的声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型。
答案 1 :(得分:0)
以下作品:
struct MyClass {
auto foo();
};
auto MyClass::foo() {
return 10;
}
虽然我不知道为什么你的案子不起作用。
(Jonathan answer,现在我知道了)