断言调用返回的函数的签名 &(引用)

Assert signature of the function that is called to return & (reference)

本文关键字:引用 调用 返回 函数 断言      更新时间:2023-10-16

是否可以断言我调用以通过引用返回的函数的类型?

断言应仅在编译时发生(但不是必需的)。

它对于调试目的很有用。

我有一个简单的std::vector<T>封装器,如下所示:-

template<class T> class CustomArray{
    //..... some datastructure ...
    T& get(int index) { ... }
}

某些游戏/业务逻辑可能会使用此类,例如

CustomArray<CreditCard> array ;
//... do some business logic
CreditCard& c= array.get(0);
c.pinNumber = 1403; //modification

pinNumber 的修改会影响自定义数组中的值,很好。

如果我团队中的某个人想使用他自己的数据结构并编辑我的代码,例如

HisCustomArray<CreditCard> array ;
//replace the line : CustomArray<CreditCard> array 

我想要一种自动的方式来确保 HisCustomArray::get(int) 始终以 T&而不是 T 返回,否则该行将被破坏。

 c.pinNumber = 1403;

我期望类似于:

CustomArray<CreditCard> array ;
assertReturn_JUST_DUMMY(   array::get(int)  , CreditCard& ); //possible format
//.... other business logic ....
您可以使用

static_assertstd::is_reference来获取所需的内容。

例:

#include <type_traits>
template<class T> class CustomArray{
   public:
    T& get(int index) {return data;}
    T data;
};
template<class T> class HisCustomArray{
   public:
    T get(int index) {return data;}
    T data;
};
struct CreditCard {};
int main()
{
   CustomArray<CreditCard> array1;
   static_assert(std::is_reference<decltype(array1.get(0))>::value,
                 "Need a reference returning function.");
   CreditCard& c1 = array1.get(0);
   HisCustomArray<CreditCard> array2;
   static_assert(std::is_reference<decltype(array2.get(0))>::value,
                 "Need a reference returning function.");
}
编译器

在编译器时对 array2 执行断言。

来自 g++ 4.8.4 的错误消息:

socc.cc: In function ‘int main()’:
socc.cc:24:4: error: static assertion failed: Need a reference returning function.
    static_assert(std::is_reference<decltype(array2.get(0))>::value, "Need a reference returning function.");

你实际上不需要做任何事情(除了使用符合标准的编译器(1))。C++ 不允许将非const引用绑定到临时引用。所以有了这个代码:

CreditCard& c= array.get(0);
c.pinNumber = 1403; //modification

如果array.get(0)碰巧按值返回,您将当场收到编译错误。


(1) Visual Studio 的编译器有一个扩展,在默认设置中启用,它允许它绑定对临时变量(实际上是右值)的引用。您可以使用/Za禁用此扩展