有没有办法为模板化函数声明类型名

Is There a Way to Declare a typename for a Templatized Function?

本文关键字:函数 声明 类型 有没有      更新时间:2023-10-16

所以,我有这个模板化的函数(我知道它看起来很丑陋。

不过,我的意图不是默认模板参数,我的目的是创建一个派生自Ttypename,该可用于用户无法分配的caster

我的问题是如何为用户无法作为参数传递的模板化函数创建typename

举个例子:

template <typename T>
typename R = std::conditional<sizeof(T) == 4, char, short>;
R foo(T bar){return R(bar);}

显然,这段代码无法编译,但这就是我想要完成的行为。函子是唯一的方法吗?

在 C++14 中,使用返回类型推导可以优雅地解决这个问题。

// C++14
#include <type_traits>
template <typename T>
decltype(auto)
foo(T bar)
{
  using R = std::conditional_t<sizeof(T) == 4, char, short>;
  return static_cast<R>(bar);
}

在 C++11 中,您必须重复类型计算。

// C++11
#include <type_traits>
template <typename T>
typename std::conditional<sizeof(T) == 4, char, short>::type
foo(T bar)
{
  using R = typename std::conditional<sizeof(T) == 4, char, short>::type;
  return static_cast<R>(bar);
}

这可以通过使用decltype来找出类型来缩短一点。

// C++11
#include <type_traits>
template <typename T>
typename std::conditional<sizeof(T) == 4, char, short>::type
foo(T bar)
{
  using R = decltype(foo(bar));
  return static_cast<R>(bar);
}

但坦率地说,使用简单的默认类型参数有什么问题?

// C++11
#include <type_traits>
template <typename T,
          typename R = typename std::conditional<sizeof(T) == 4, char, short>::type>
R
foo(T bar)
{
  return static_cast<R>(bar);
}

请注意,我已将 return 语句中 R 的值初始化替换为一个static_cast,以静音编译器关于缩小转换的警告。 不过,您确定这是您想要的吗?

一种可能性是使用using类型别名而不是typename 。以下代码在我测试的编译器上编译(记住启用-std=c++11标志(。

#include <type_traits>
#include <iostream>
// C++11
template <typename T>
using R = typename std::conditional<sizeof(T) == 4, char, short>::type;
template <typename T>
R<T> foo(T bar){return R<T>(bar);}
int main() {
  std::cout << foo(13.0) << std::endl;
  return 0;
}

在 C++14 中,您可以使用 conditional_t 特征,这更简单。

// C++14
template <typename T>
using R = std::conditional_t<sizeof(T) == 4, char, short>;