如何让编译器推导出C++ 11中模板化方法的返回类型?

Pat*_* B. 2 c++ methods templates return-type c++11

我有一个模板化方法,其中return-type将是reinterpret_cast <>() - 调用的结果.

class A {
    void *_ptr;
public:
    template<typename T>
    T buffer() { return reinterpret_cast<T>(_ptr); }
};
Run Code Online (Sandbox Code Playgroud)

这种方式让我<>在调用这个函数时使用-syntax:

A a;
auto b = a.buffer<double *>();
Run Code Online (Sandbox Code Playgroud)

我更喜欢在没有模板参数的情况下调用此方法,并让编译器根据变量类型推断出返回类型.

A a;
double *out = a.buffer();
Run Code Online (Sandbox Code Playgroud)

返回型扣除是否可行?

我尝试使用auto,该->-operand和尾随返回类型的语法.

auto buffer() -> decltype(reinterpret_cast<T>(_ptr)) const 
     { return reinterpret_cast<T>(_ptr); }
Run Code Online (Sandbox Code Playgroud)

但它仍然无效.

在C++ 11中有没有办法做到这一点?

eca*_*mur 10

是的,但只能通过具有转换功能模板的代理类型:

struct BufferProxy {
  void* ptr;
  template<class T> operator T*() { return reinterpret_cast<T*>(ptr); }
};
BufferProxy buffer() { return BufferProxy{_ptr}; }
Run Code Online (Sandbox Code Playgroud)

例子.

请注意,熟悉auto返回类型推导使用的用户可能会对此技术感到困惑:

auto out = a.buffer(); // out is BufferProxy 
auto* out = a.buffer(); // fails to compile; can't deduce 'auto*' from 'a.A::buffer()'
Run Code Online (Sandbox Code Playgroud)

直到C++ 17,您可以auto out = a.buffer();通过提供BufferProxy已删除的复制构造函数(并且可能通过聚合构造返回:) 来阻止编译 return {_ptr};,但是用户仍然可以使用auto&&和来自C++ 17 保证复制省略将使auto表单再次工作.