我有一个函数来确定模板类型是否为指针。
session_start();
if (!isset($_SESSION['nID']) || empty($_SESSION['nId'])) {
header("Location: login.php");
die();
}
我有一个初始化函数。
template<class T>
struct is_pointer_struct { static const bool value = false; };
template<class T>
struct is_pointer_struct<T*> { static const bool value = true; };
template<class T>
bool is_pointer(T &var) {
return is_pointer_struct<T>::value;
}
显然,当template<class T>
void initialize(T &val) {
if (is_pointer(val))
val = NULL;
else
val = T();
}
为T
时,无法编译此代码。有什么方法可以在string
是指针类型时编译val = NULL
并在T
不是指针类型时编译val = T()
?
答案 0 :(得分:20)
在您的特定情况下,您可以使用统一初始化,因为VTT说:
val = T{};
此外,标准库提供std::is_pointer
。
作为对更一般问题的回答
在C ++ 17中,您所要做的就是将if(...)
更改为if constexpr(...)
:
template<class T>
void initialize(T &val) {
if constexpr(is_pointer(val))
val = nullptr;
else
val = T();
}
在C ++ 14中,您can implement your own static_if
。
在C ++ 03/11中,您可以使用标签分派:
template <typename T>
void initialize_impl(std::true_type /* pointer */, T& val)
{
val = NULL;
}
template <typename T>
void initialize_impl(std::false_type /* non-pointer */, T& val)
{
val = T();
}
template<class T>
void initialize(T &val) { initialize_impl(std::is_pointer<T>{}, val); }
答案 1 :(得分:6)
在你的情况下做正确的事情的正确方法是使用统一初始化,如上所述。
作为一个选项,您可以根据您的类型特征使用 SFINAE ,这样就可以实例化必要的模板(这里是 C ++ 11 方法) :
template<class T>
auto initialize(T &val) ->
typename std::enable_if<is_pointer_struct<T>::value>::type {
val = nullptr;
}
template<class T>
auto initialize(T &val) ->
typename std::enable_if<!is_pointer_struct<T>::value>::type {
val = T();
}
答案 2 :(得分:6)
经典解决方案,甚至不需要C ++ 11功能:简单的重载:
template<class T>
void initialize(T& val)
{
val = T();
}
template<class T>
void initialize(T*& val)
{
val = NULL;
}
但是,第一个重载(在特定情况下)也包含指针,所以第二个实际上已经过时了。
无论是否过时,我希望nullptr
关键字超过NULL
宏(尽管再次失去了C ++ 11之前的兼容性)。