【问题标题】:How I can find type of template function return如何找到模板函数返回的类型
【发布时间】:2019-04-02 12:47:51
【问题描述】:

我需要找到类似这样的模板函数结果类型:

template<typename T>
T fun1(
T arg1,
result_fun<T>(some_fun)
);

或者类似的东西。所以在标准库中我找到了result_of(我也找到了invoke_result,它也不起作用)。所以我找到了post,在那里我找到了这个函数的语法。它适用于 sipmle 代码 but... 它不适用于指针... 示例(它和 ideone 代码相等):

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
T *some(T x){
    return &x;
}

template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z);

template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z){
    cout << is_same<decltype(x), int>() << endl
     << is_same<decltype(z), int *>();
}

int main(){
    int x = 0;
    int *z = nullptr;
    somestrange(x, z);
    return 0;
}

它会工作,但如果模板接收指针......

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
T **some(T *x){
    return &x;
}

template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z);

template<typename T>
void somestrange(T x, typename result_of<decltype(&some<decltype(x)>)(decltype(x))>::type z){
    cout << is_same<decltype(x), int>() << endl
     << is_same<decltype(z), int *>();
}

int main(){
    int *x = 0;
    int **z = nullptr;
    somestrange(x, z);
    return 0;
}

编译会生气。所以我想我能做些什么。我创造了自己的轮回......所以我写了this之类的东西:

#include <iostream>
#include <type_traits>
#include <utility>
#include <typeinfo>

using namespace std;

template<typename Fun, typename Arg>
inline auto myinvoke(Fun&& f, Arg&& arg)
    -> decltype(forward<Fun>(f)(forward<Arg>(arg)))
{
    return (forward<Fun>(f)(forward<Arg>(arg)));
}

template<typename Fun, typename Arg>
struct return_type {
    using type = decltype(myinvoke(declval<Fun>(), declval<Arg>()));
};

template<typename Fun, typename Arg>
using return_type_t = typename return_type<Fun, Arg>::type;


template <typename T>
T *some(T x){
    return &x;
}

template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z);

template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z){
    cout << is_same<decltype(x), int>() << endl
     << is_same<decltype(z), int *>();
}

int main(){
    int x = 0;
    int *z = nullptr;
    somestrange(x, z);
    return 0;
}

但如果我在这里,你可以猜到它不起作用。你会是对的,因为它不适用于ptr,同样不能使用 result_of:

#include <iostream>
#include <type_traits>
#include <utility>
#include <typeinfo>

using namespace std;

template<typename Fun, typename Arg>
inline auto myinvoke(Fun && f, Arg&& arg)
    -> decltype(forward<Fun>(f)(forward<Arg>(arg)))
{
    return (forward<Fun>(f)(forward<Arg>(arg)));
}

template<typename Fun, typename Arg>
struct return_type {
    using type = decltype(myinvoke(declval<Fun>(), declval<Arg>()));
};

template<typename Fun, typename Arg>
using return_type_t = typename return_type<Fun, Arg>::type;


template <typename T>
T **some(T *x){
    return &x;
}

template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z);

template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z){
    cout << is_same<decltype(x), int>() << endl
     << is_same<decltype(z), int *>();
}

int main(){
    int *x = 0;
    int **z = nullptr;
    somestrange(x, z);
    return 0;
}

那么我能用它做什么呢?有人知道我该如何解决这个问题(我只能使用 STL)?谢谢解答

【问题讨论】:

  • some 通过从局部变量返回指针具有未定义的行为。
  • 我知道我,不要使用这个结果它需要我解释问题,抱歉
  • 使用指针,您需要return_type_t&lt;decltype(some&lt;T&gt;), T*&gt;,因为T 不是some&lt;T&gt; 的有效输入参数。
  • 添加可以使用this获取任意函数对象的返回类型。
  • 为什么?在第四个例子中,T 是 int*

标签: c++ visual-c++ compiler-errors c++17


【解决方案1】:

int *x = 0;
int **z = nullptr;
somestrange(x, z);

template<typename T>
void somestrange(T x, return_type_t<decltype(some<T>), T> z);
  • T 将是 int*
  • some&lt;T&gt; 期望 T* 参数

所以改成

template<typename T>
void somestrange(T* x, return_type_t<decltype(some<T>), T*> z);

template<typename T>
void somestrange(T* x, return_type_t<decltype(some<std::remove_pointer_t<T>>), T> z);

Demo

或者不明确指定模板,允许推演:

template<typename T>
void somestrange(T x, decltype(some(std::declval<T>())) z);

Demo

【讨论】:

  • 它可以工作,但是在我的代码中我有接收指针或智能指针的函数(比如一些奇怪的),所以我不能这样使用
  • @emik_g: 其他方式添加。
猜你喜欢
  • 2012-06-21
  • 1970-01-01
  • 2021-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-04
  • 1970-01-01
相关资源
最近更新 更多