c++ - 如何根据返回类型编写模板化自由函数

标签 c++ templates return-type-deduction

<分区>

我有一个与函数返回值的类型推导相关的问题。

首先,一些上下文,以显示我的期望。 假设我有这个函数模板:

template <typename T1, typename T2>
T1 foo( T2 t )
{
    T1 a = static_cast<T1>(t); // dummy conversion,
    return a;                  // just there to use t
}

然后,这不会构建,因为返回类型不能用于类型推导:

int a;
float v1 = foo(a);
char  v2 = foo(a);

但是如果我添加请求的类型,那就没问题了:

int a;
auto v1 = foo<float>(a);
auto v2 = foo<char>(a);

现在是我的问题。我有一个类,它提供了一些数据的 setter/getter :

template<typename T>
struct MyClass
{
   T data;
   template<typename U>
   U get() { return static_cast<U>(data); }  // dummy code, returns an 'U'
};

用户代码可以用这个获取数据(构建良好):

MyClass<int> m;
auto v3 = m.get<float>();

但我想通过使用免费函数为用户代码提供第二种访问数据的方式,因此可以编写:

MyClass<int> m;
auto v4 = ff_get<float>(m);

问题是: 如何编写 ff_get()

我试过:

template <typename T1, typename T2>
T1 ff_get( T2 t )
{
    return t.get<T1>();
}

但这不会构建,尽管在我看来它使用与上面的 foo 调用相同的语法。所以问题的第二部分是:为什么会失败?

(参见 live code)

最佳答案

转换返回类型而不是推导它

您可以为您的返回类型创建一个转换代理对象。这会将返回类型推导转移到模板转换操作中。

template <typename T>
struct foofoo {
    T t_;
    foofoo (T t) : t_(t) {}
    template <typename U>
    operator U () const { return static_cast<U>(t_); }
};

template <typename T>
foofoo<T> foo( T t )
{
    return foofoo<T>(t);
}

应用于 MyClass,您的 getter 可以类似地实现:

template<typename T>
struct MyClass
{
   T data;
   foofoo<T> get() { return foofoo<T>(data); }
};

然后,这段代码就可以正常工作了:

MyClass<int> m;
float v3 = m.get();

推断getter的返回类型

现在,要实现 ff_get,它主要是一个简单的函数实现,除了返回类型现在是从 get 方法本身推导出来的。在 C++11 中,您将使用尾随返回类型语法。

template <typename T>
auto ff_get (T t) -> decltype(t.get())
{
    return t.get();
}

从 C++ 14 开始,您可以完全删除尾随返回类型,因为返回类型没有歧义。

template <typename T>
auto ff_get (T t)
{
    return t.get();
}

关于c++ - 如何根据返回类型编写模板化自由函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67975845/

相关文章:

c++ - 如何将 memcpy 与 unique_ptr 一起使用

c++ - 为什么这个模仿 `vector` 的迭代器初始化的构造函数可以工作?

javascript - 如何使用 session 和模板来显示/隐藏元素?

c++ - 将类型插入/删除可变参数模板列表(参数包)

c++ - 在调用函数之前如何推断 auto ?

c++ - 带 IEEE 754 float 的有效数字

C++11 在 map<key, value> 中为值(int 和 string)存储多种数据类型的最简单方法?

C++,初始化类的模式

c++ - Koenig 查找的尾随返回类型和回退

c++ - 尾随返回类型中的占位符是否会覆盖初始占位符?