如何定义自定义跨平台size_t类型?

时间:2017-06-13 11:28:53

标签: c++ c++11 c++03 size-t size-type

std::size_t通常用于数组索引和循环计数。根据定义,std::size_tsizeof运算符以及sizeof...运算符和alignof运算符(自C ++ 11以来)的结果的无符号整数类型。它在以下标题中定义:

  • <cstddef>
  • <cstdio>
  • <cstdlib>
  • <cstring>
  • <ctime>
  • <cwchar>

根据我的理解,这些运算符返回的类型是实现定义的。

我想要的是定义自定义size_t,以避免从我上面的.cpp文件中提到的任何标题中提取不必要的内容,因为在我的文件中我只需要{{ 1}}。

在C ++ 11及更高版本中,我认为我可以使用以下别名:

std::size_t

但是,我想以便携/跨平台的方式为C ++ 11之前的编译器定义using size_t = decltype(sizeof(1)); 类型。

那么有一种可移植的方法来为C ++ 11之前的版本定义size_t吗?

3 个答案:

答案 0 :(得分:4)

据我所知,您已经列出了获得func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) { print("Successfully logged into google", user) guard let idToken = user.authentication.idToken else {return} guard let accessToken = user.authentication.accessToken else {return} let credential = GoogleAuthProvider.credential(withIDToken: idToken, accessToken: accessToken) Auth.auth().signIn(with: credential) { (user, error) in if error != nil{ print("ANKIT : Unable to authenticate with firebase") } else{ guard let uid = user?.uid else { return } KeychainWrapper.standard.set(uid, forKey: KEY_UID) self.window?.rootViewController?.performSegue(withIdentifier: "goToFeed", sender: nil) print("ANKIT : Successfully authenticated with firebase for google") } } } 的唯一两种跨平台方式:包括标准头文件或decltype(自C ++ 11以来)的定义。但两者都明确无法使用。

第三个选项是手动移植,即使用预定义的宏来检测环境,并从手动维护的typedef列表中选择正确的typedef。例如,在GCC上,您可以使用__SIZE_TYPE__(但是,请考虑文档中的警告,即不应该直接使用宏,并且不在所有平台上提供它)。在其他编译器上,您将使用其他东西。

答案 1 :(得分:4)

理论上,如果列出size_t的所有可能(未签名)候选人并不打扰你,你可以使用SFINAE:

template <class T, class N = void, bool = sizeof(T) == sizeof(sizeof(T))>
struct TL { 
    typedef typename N::type type;
};

template <class T, class N>
struct TL<T, N, true> {
    typedef T type;
};

typedef TL<unsigned short,TL<unsigned int, TL<unsigned long, TL<unsigned long long> > > >::type SizeT;

[live demo]

修改

针对unsigned longunsigned long long进行区分的编译器的解决方法,尽管他们假设sizeof(unsigned long) == sizeof(unsigned long long)

template <class U>
U *declptrval(U);

template <class U>
char is_exact(U *);

template <class U>
short is_exact(...);

template <class T, class N = void, bool = sizeof(is_exact<T>(declptrval(sizeof(T))))==sizeof(char)>
struct TL { 
    typedef typename N::type type;
};

template <class T, class N>
struct TL<T, N, true> {
    typedef T type;
};

typedef TL<unsigned short,TL<unsigned int, TL<unsigned long, TL<unsigned long long> > > >::type SizeT;

[live demo]

答案 2 :(得分:0)

不幸的是,“实现定义”包括头文件,而不仅仅是编译器本身。如果你看[expr.sizeof],他们似乎建议只使用它:

#include <cstddef>