当我在启用C ++ 11的情况下编译代码时,我可以使用以下代码。还可以编写专门化的代码,使其可以与C ++ 98编译器一起工作吗?
#include <iostream>
#include <type_traits>
#include <cstdint>
template<typename T, typename std::enable_if_t<!std::is_pointer<T>::value, int> = 0>
void CheckSize(T const)
{
cout << "sizeof(data): " << sizeof(T) << endl;
}
template<typename T, typename std::enable_if_t<std::is_pointer<T>::value, int> = 0>
void CheckSize(T const)
{
cout << "sizeof(data) (pointer): " << sizeof(std::remove_pointer<T>) << endl;
}
template<typename T, size_t N>
void CheckSize(T const (&)[N])
{
cout << "sizeof(data) (array): " << sizeof(T) * N << endl;
}
int main()
{
uint8_t bufferNumber{0};
CheckSize(bufferNumber);
uint8_t bufferArray[] = {1,2,3,4,5,6};
CheckSize(bufferArray);
uint8_t *bufferPointer{nullptr};
CheckSize(bufferPointer);
return 0;
}
我也不明白为什么编译器在编写时不能应用特殊化:
template<typename T>
void CheckSize(T const)
{
cout << "sizeof(data): " << sizeof(T) << endl;
}
template<typename T>
void CheckSize(T const*)
{
cout << "sizeof(data) (pointer): " << sizeof(T) << endl;
}
MSVC2015将显示一条错误消息,指出函数调用对于bufferArray
变量的重载函数是模棱两可的,而MinGW将对CheckSize(T const)
变量使用bufferPointer
函数。
答案 0 :(得分:2)
如注释中所述,enable_if
和您使用的类型特征可以使用C ++ 98实现。 Boost提供了实现,如果您已经在使用boost,我建议您使用它们,但是如果您没有使用boost,它们将很容易实现:
template <bool b, typename T>
struct enable_if;
template <typename T>
struct enable_if<true, T>
{
typedef T type;
};
template <typename T>
struct is_pointer
{
const static bool value = false;
};
template <typename T>
struct is_pointer<T*>
{
const static bool value = true;
};
template <typename T>
struct remove_pointer
{
typedef T type;
};
template <typename T>
struct remove_pointer<T*>
{
typedef T type;
};
template<typename T>
typename enable_if<!is_pointer<T>::value, void>::type
CheckSize(T const)
{
std::cout << "sizeof(data): " << sizeof(T) << std::endl;
}
template<typename T>
typename enable_if<is_pointer<T>::value, void>::type
CheckSize(T const)
{
std::cout << "sizeof(data) (pointer): " << sizeof(typename remove_pointer<T>::type) << std::endl;
}
template<typename T, size_t N>
void CheckSize(T const (&)[N])
{
std::cout << "sizeof(data) (array): " << sizeof(T) * N << std::endl;
}
或者,您可以使用部分专业化而不是SFINAE来选择重载。由于功能不能部分专业化,因此可以对帮助器类进行部分专业化
template<typename T>
struct CheckSizeHelper
{
static void size() {
std::cout << "sizeof(data): " << sizeof(T) << std::endl;
}
};
template<typename T>
struct CheckSizeHelper<T*>
{
static void size() {
std::cout << "sizeof(data) (pointer): " << sizeof(T) << std::endl;
}
};
template<typename T, size_t N>
struct CheckSizeHelper<T[N]>
{
static void size() {
std::cout << "sizeof(data) (array): " << sizeof(T) * N << std::endl;
}
};
template<typename T>
void CheckSize(T const&) {
CheckSizeHelper<T>::size();
}
答案 1 :(得分:1)
正如评论中提到的,一种选择是使用boost::enable_if
另一种选择是对类使用部分模板特化,而不是函数重载:
#include <iostream>
#include <type_traits>
#include <cstdint>
using namespace std;
template<typename T>
struct SizeChecker
{
static void CheckSize(T const)
{
cout << "sizeof(data): " << sizeof(T) << endl;
}
};
template<typename T>
struct SizeChecker<T*>
{
static void CheckSize(T* const)
{
cout << "sizeof(data) (pointer): " << sizeof(T*) << endl;
}
};
template<typename T, size_t N>
struct SizeChecker<T[N]>
{
static void CheckSize(const T(&)[N])
{
cout << "sizeof(data) (array): " << sizeof(T) * N << endl;
}
};
template <typename T>
void CheckSize(const T& val)
{
SizeChecker<T>::CheckSize(val);
}
int main()
{
char bufferNumber{0};
CheckSize(bufferNumber);
char bufferArray[] = {1,2,3,4,5,6};
CheckSize(bufferArray);
char *bufferPointer{NULL};
CheckSize(bufferPointer);
return 0;
}