有没有办法让函数返回类型名?

Posted

技术标签:

【中文标题】有没有办法让函数返回类型名?【英文标题】:Is there a way to make a function return a typename? 【发布时间】:2016-04-10 05:59:49 【问题描述】:

我最近在做一个项目,并希望在执行非标准操作时优先考虑某些类型。为此,我试图以某种方式使用模板来确定正在使用哪种数据类型。我写的代码显然不起作用,但它让我知道我想要做什么

#include <iostream>

template <type1,type2>
typename determine(type1 a, type2 b)

    if (typeid(type1) == typeid(int) || typeid(type2) == typeid(int))
        return int;
    else return double;


int main()

    int a = 3;
    double b = 2;
    std::cout << (static_cast<determine(a, b)>(a) / static_cast<determine(a, b)>(b)) << std::endl;

有没有办法确定返回一些我可以实际用来决定使用什么数据类型的东西?

【问题讨论】:

【参考方案1】:

您可以使用template metaprogramming 技术来实现您的目标。

template <typename T1, typename T2> struct TypeSelector

   using type = double;
;

template <typename T1> struct TypeSelector<T1, int>

   using type = int;
;

template <typename T2> struct TypeSelector<int, T2>

   using type = int;
;

template <> struct TypeSelector<int, int>

   using type = int;
;

然后,使用:

int main()

    int a = 3, b = 2;
    using type1 = TypeSelector<decltype(a), decltype(b)>::type;
    std::cout << (static_cast<type1>(a) / static_cast<type1>(b)) << std::endl;

   float c = 4.5f;
   using type2 = TypeSelector<decltype(a), decltype(c)>::type;
   std::cout << (static_cast<type2>(a) / static_cast<type2>(c)) << std::endl;

   using type3 = TypeSelector<decltype(c), decltype(a)>::type;
   std::cout << (static_cast<type3>(c) / static_cast<type3>(a)) << std::endl;


【讨论】:

你有一个“与”运算——问题是一个“或”。 @DieterLücking,我意识到了,正在编辑中:) 我很确定,如果我的问题是一样的。我想通过我的 Delphi RAD Studio 调用 C++ 例程。现在我想给我们我的type Tinputvec,它是一个array of integer(动态),由delphi函数返回。现在我必须在我的 C++ 部分中使用这个命名类型。 std::vector &lt;int&gt; 与我命名的 Tinputvec 类型不匹配,并且出现编译错误。如何在我的 C++ 部分中使用我的命名类型 Tinputvec?谢谢 @WalterSchrabmair,我没有答案。【参考方案2】:

我很确定您可以使用 std::conditional 和几个 std::is_same 限定符通过 || 逻辑组合来做到这一点:

#include <iostream>
#include <type_traits>


template<class T1, class T2>
using determine = typename std::conditional<
    std::is_same<T1,int>::value || std::is_same<T2,int>::value, 
    int, double>::type;

int main()

    int a = 3;
    double b = 2;
    long c = 3L;

    using type1 = determine<decltype(a),decltype(b)>;
    std::cout << (static_cast<type1>(a) / static_cast<type1>(b)) << std::endl;

    using type2 = determine<decltype(b),decltype(c)>;
    std::cout << (static_cast<type2>(b) / static_cast<type2>(c)) << std::endl;

【讨论】:

@rtpax 如果您想以函数形式使用它,您可以使用尾随返回类型以及此答案中的别名。【参考方案3】:

这是您可以使用的另一种可行的解决方案。 基本思想是依靠函数重载和sfinae来分派请求,避免多重定义。 它遵循一个最小的工作示例:

#include<type_traits>
#include<utility>
#include<cassert>

template <typename T1, typename T2>
typename std::enable_if<std::is_same<T1, int>::value or std::is_same<T2, int>::value, int>::type
determineImpl(int, T1 a, T2 b) 
    return 42;


template <typename T1, typename T2>
typename std::enable_if<not std::is_same<T1, int>::value and not std::is_same<T2, int>::value, double>::type
determineImpl(char, T1 a, T2 b) 
    return .42;


template<typename... Args>
auto determine(Args&&... args) -> decltype(determineImpl(0, std::forward<Args>(args)...)) 
    return determineImpl(0, std::forward<Args>(args)...);


int main() 
    auto v1 = determine(42, 'c');
    assert(v1 == 42);
    auto v2 = determine('c', .42);
    assert(v2 == .42);

【讨论】:

以上是关于有没有办法让函数返回类型名?的主要内容,如果未能解决你的问题,请参考以下文章

如何正确键入返回 TypeScript 中的类的函数?

Kotlin函数 ② ( Unit 函数 | TODO 函数抛出异常返回 Nothing 类型 | 反引号函数名 )

在 C++ 中使用成员函数向量时,有没有办法实现协变返回类型?

java函数

JAVA函数的返回值类型详解以及生成随机数的例题

3.13课·········函数