我可以在C++中部分编译模板函数吗?

Can I partial compile a template function in C++

本文关键字:函数 编译 C++ 中部 我可以      更新时间:2023-10-16

我有一个函数来确定模板类型是否为指针。

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();
}

显然,当Tstring时,这段代码是无法编译的。有没有办法在T是指针类型时编译val = NULL,当T不是指针类型时编译val = T()

在您的特定情况下,您可以使用统一初始化,如 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 中,您可以实现自己的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); }
    

如前所述,在您的情况下执行操作的正确方法是使用统一初始化。

作为一种选择,您可以根据您的类型特征使用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();
}

经典解决方案,甚至不需要 C++11 功能: 简单重载:

template<class T>
void initialize(T& val)
{
val = T();
}
template<class T>
void initialize(T*& val)
{
val = NULL;
}

但是,第一个重载(在特定情况下(也涵盖了指针,因此第二个重载实际上已经过时了。

不考虑过时,我更喜欢nullptr关键字而不是NULL宏(尽管再次失去了 C++11 之前的兼容性(。