我有一个函数来确定模板类型是否为指针.
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;
}
Run Code Online (Sandbox Code Playgroud)
我有一个初始化函数.
template<class T>
void initialize(T &val) {
if (is_pointer(val))
val = NULL;
else
val = T();
}
Run Code Online (Sandbox Code Playgroud)
显然,当T是string,此代码不能被编译.有没有一种方法可以val = NULL在T指针类型时编译并val = T()在T不是指针类型时编译?
Vit*_*meo 20
在您的特定情况下,您可以使用统一初始化,因为VTT说:
val = T{};
Run Code Online (Sandbox Code Playgroud)
此外,标准库提供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();
}
Run Code Online (Sandbox Code Playgroud)在C++ 14中,您可以实现自己的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); }
Run Code Online (Sandbox Code Playgroud)在你的情况下做正确的事情的正确方法是使用统一初始化,如上所述.
作为一个选项,您可以根据您的类型特征使用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();
}
Run Code Online (Sandbox Code Playgroud)
经典解决方案,甚至不需要C++ 11功能:简单的重载:
template<class T>
void initialize(T& val)
{
val = T();
}
template<class T>
void initialize(T*& val)
{
val = NULL;
}
Run Code Online (Sandbox Code Playgroud)
但是,第一个重载(在特定情况下)也包含指针,因此第二个重载实际上是过时的.
无视过时,我更喜欢nullptr关键字而不是NULL宏(虽然再次失去了预C++ 11的兼容性).
| 归档时间: |
|
| 查看次数: |
1323 次 |
| 最近记录: |