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

标签 c++ templates c++11 methods return-type

我有一个模板化方法,其中返回类型将是 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}; }

Example .

请注意,熟悉使用 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 guaranteed copy elision将使 auto 表单再次工作。

关于c++ - 如何让编译器推断出 C++11 中模板化方法的返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39573223/

相关文章:

c++ - 使用 std::iterator_traits<> 时出现不清楚的编译时错误

c++ - Visual Studio 2010 中未解析的外部符号

gcc 7.5 上的 C++ 隐式转换和通用转发

c++ - 基于 SFINAE 的重载冲突

c++ - 使用 Android Studio 构建共享 *.so 库的发布版本

c++ - 具有 const 不可复制元素的元组

c++ - 在运行时检查动态库的兼容性

c++ - 使用 std::set<myOwnObjectType> 是问题的根源吗?

python - 模板中的 django forloop 计数器

c++ - 为什么 "extern template"不能与 shared_ptr 一起使用?