如何让编译器推断出c++ 11中模板化方法的返回类型
How to have the compiler deduce the return type of a templated method in C++11?
我有一个模板方法,其中返回类型是reinterpret_cast<>()调用的结果。
class A {
void *_ptr;
public:
template<typename T>
T buffer() { return reinterpret_cast<T>(_ptr); }
};
这种方式使我在调用这个函数时使用<>
-语法:
A a;
auto b = a.buffer<double *>();
我更倾向于不带模板参数调用这个方法,让编译器根据变量类型推断返回类型。
A a;
double *out = a.buffer();
对于返回类型演绎是否可能?
我尝试使用auto
, ->
-操作数和尾部返回类型语法。
auto buffer() -> decltype(reinterpret_cast<T>(_ptr)) const
{ return reinterpret_cast<T>(_ptr); }
但是它仍然不能工作。
在c++ 11中有什么办法做到这一点吗?
可以,但只能通过具有转换函数模板的代理类型:
struct BufferProxy {
void* ptr;
template<class T> operator T*() { return reinterpret_cast<T*>(ptr); }
};
BufferProxy buffer() { return BufferProxy{_ptr}; }
的例子。
注意,熟悉使用auto
进行返回类型推断的用户可能会对这种技术感到困惑:
auto out = a.buffer(); // out is BufferProxy
auto* out = a.buffer(); // fails to compile; can't deduce 'auto*' from 'a.A::buffer()'
直到c++ 17,你可以通过给BufferProxy
一个删除的复制构造函数来防止auto out = a.buffer();
编译(也许通过聚合构造:return {_ptr};
返回它),但是用户仍然可以使用auto&&
,并且从c++ 17开始保证复制省略将使auto
形式再次工作。
您可能想要一个像下面这样的类。这似乎提供了你想做的大部分事情。
我想知道的一个问题是如何确定存储在类中的指针是否为相同类型。因此,我认为最好添加一个额外的方法来使用hash_code()
方法检查typeid()
。
所以我想到的类使用operator
的想法@ecatmur在他/她的答案:
class A {
void *_ptr;
size_t _ptrHash;
public:
template<typename T> operator T*() { return reinterpret_cast<T *>(_ptr); }
template<typename T>
void SetPtr(T *p) { _ptr = p; _ptrHash = typeid(*p).hash_code(); }
template<typename T> bool operator == (T *p) { return p && typeid(*p).hash_code() == _ptrHash /* && p == _ptr */; }
};
相等操作符可以像上面那样只检查类型,或者如果取消了额外的检查注释,也可以检查指针的值。您可能只是想检查类型。
我用了一个简单的演示函数来测试它,如下所示:void funky1() {
A a;
double ddd[50] = { 0.0 };
ddd[0] = 5.0; ddd[2] = 7.0;
a.SetPtr(&ddd[0]);
double *p = a;
bool bb = a == p;
long lll[50] = { 0 };
lll[0] = 5; lll[2] = 7;
long *q = a;
bb = a == q;
a.SetPtr(&lll[0]);
q = a;
bb = a == q;
}
我用调试器Visual Studio 2013完成了这个步骤,看起来它像一个冠军。
我想这个答案是最优雅的。
无论如何,你也可以让类像这样初始化你的指针:
class A {
void *_ptr;
public:
template<typename T>
void buffer(T **t) { *t = reinterpret_cast<T*>(_ptr); }
};
int main() {
A a;
double *b;
a.buffer(&b);
}
这种方式的类型是从参数列表中推断出来的,您不必显式指定它。
相关文章:
- 我的模板类方法返回错误类型?
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- 具有引用返回类型的重写方法上的协变返回类型无效
- Arduino trim() 和 replace() 方法返回从 'void' 到非标量类型'String'请求的转换
- Java 调用 dll 字符串返回类型方法
- 必须使用尾随返回类型的示例,因为无法用旧方法解决问题
- 如何拥有两个名称相同但返回类型不同的纯虚拟方法
- 可能从单个方法返回不同类型的对象
- qml 未知方法返回类型:ArchiveFile*,即使调用了 qmlRegisterUncreatableType
- std::d eclval vs crtp,无法从不完整类型推断方法返回类型
- 将返回类型推断为模板参数类型方法
- dlsym() 解决方法返回类型
- 我如何根据某些模板参数影响模板类方法的返回类型
- 如何检查模板类方法返回类型
- 覆盖方法返回类型,在C 中使用不完整的派生类
- 类成员方法 - 返回类型模板
- C++中具有多态模板类的未知方法返回类型
- 是否可以使用Boost概念检查库验证方法返回类型
- 使用不同方法返回类型的C++模板类设计