C++11 : How can I define a function that accept a universal reference of a specific type of object?

标签 c++ c++11

问题: 我正在用 C++11 开发一个程序。我想编写一个接受右值引用和左值引用的函数。 (即通用引用)。

以下函数接受通用引用参数:

template<class T> void function(T&& t){/*SNIP*/}

但是,它接受所有类型的参数。它破坏了函数的类型安全。想让它接受特定类型的参数怎么办?

这是我能想到的解决方案:

void function(Class& t){/*SNIP*/}
void function(Class&& t){ function(t); }

然而,它很丑陋。如果我想更改要接受的参数或更改函数名称,我必须更新函数的两个版本。有比这更好的等价物吗?

编辑:问题已解决。你们都回答得很好。我对两个答案都投了 +1 票以表示感谢。我将把这个问题留几天。得票最多的答案将被接受。

EDIT2:我最终得到以下代码:

template < class T,
class=typename std::enable_if<std::is_same<Class, typename std::decay<T>::type>::value>::type //Dummy template parameter
>
void function(T&&){}

EDIT3:我为此编写了一个宏定义:

#define uRefType(T, typeLimit) class T, class=typename std::enable_if<std::is_same<typename std::decay<T>::type, typeLimit>::value>::type

使用示例:

template< uRefType(T, Class) > void function(T&&){}

最佳答案

这样做的一种方法是使用 std::enable_if .这是 type_traits 提供的结构 header 。它的定义方式是 enable_if<A,B>::type是类型 B如果 bool 条件 A在编译时评估为真。否则为空。

因此,如果你有一个函数模板

template <typename T>
void fun(T &&)
{ /*...*/ }

并且您希望确保它仅在 T 时被定义是某种类型,你可以使用enable_if<...>::type构造而不是返回类型(此处为 void )。 bool 条件 A然后被定义为: Tint 和类型 B被定义为函数的原始返回类型(此处为 void )。

所以,如果我们想要 fun仅在 T 时被定义是int ,我们得到这个:

#include <type_traits>

template <typename T>
typename std::enable_if<std::is_same<int,typename std::decay<T>::type>::value,void>::type
fun(T &&)
{ }

int main()
{
  int    lvali = 3;
  double lvald = 3.3;

  fun(3);
  fun(lvali);

  // fun(3.3);      // this won't be accepted (not an int)
  // fun(lvald)     // this won't be accepted (not an int)

  return 0;
}

请注意 bool 条件是如何定义如下(省略 std:: 以提高可读性):

is_same<int,typename decay<T>::type>::value

decay语句用于确保无论 T 是否有效都有效。是intint & (还有一些特殊情况)。


进一步说明:这种技巧只有在相关函数的定义对于右值和左值都相同时才真正有用。在许多情况下情况并非如此(因为右值情况将实现移动,左值情况不会,或类似情况)。

两个定义实际上相同的典型情况是函数体非常短,除了将参数转发给另一个(可能重载的)函数调用外什么都不做:

template <typename T>
void fun(T &&obj)
{ other_fun(std::forward<T>(obj)); }

在这种情况下,不使用任何 enable_if 可能是可以的或其他技巧,因为 other_fun 的声明将确保最终只接受某些类型。

关于C++11 : How can I define a function that accept a universal reference of a specific type of object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14918984/

相关文章:

c++ - 是否有必要在每一帧绑定(bind)所有 VBO(和纹理)?

c++ - 如何在MFC中查找系统是否有我需要的字体?

c++ - 连接 vector 的 Constexpr 函数

c++ - 将函数放入 vector 并执行

C++ ODB 数据库映射器:无法在关系中使用 std::weak_ptr

C++ - 使用在 azure 中托管的 C# REST-full WCF 服务

c++ - 剪切和粘贴后监视文件(Windows Shell 扩展?)

c++ - 可变参数模板成员函数的部分特化

c++ - 如何使用alignas替换pragma pack?

c++ - 静态 LPTSTR 变量在函数执行后丢失值