c++ - 模板函数实现中的条件取决于类型是否为指针

标签 c++ templates pointers

所以我有了这个模板函数。 它应该在一个名为 AbstractEvent 的更复杂的结构中设置一个变量:

template< typename T >

void AbstractEvent::setVar( QString varName, T value) 
{
    if (std::is_pointer<T>::value)
    {
        void * castValue = static_cast<void*>(value);
        if (castValue)
        {
            //do sth with castValue
        }

     }
     else
     {
        //do something with value
     }
}

使用此模板函数,我想将变量“值”存储在 QVariant 中,然后将 QVariant 存储在某处。

如果“值”是一个指针,我想将它作为一个 void* 存储在 QVariant 中。对于其他任何我想存储真实类型的内容。

我尝试使用 C++ 特性 std::is_pointer::value 来检查值是否为指针。

这段代码编译得很好,但是当我尝试使用它时,例如:

int intValue = 0;
setVar<int>("aVar",intValue);

我收到这个错误:

error C2440: 'static_cast' : unable to convert from 'int' to 'void *'

我认为编译器很困惑,因为它正在检查这一行:

    void * castValue = static_cast<void*>(value);

当然,当 value 不是指针时,这就没有意义了。这就是我的 if 语句

     if (std::is_pointer<T>::value)

应该避免,但是,即使在运行时,这段值为 int 的代码也永远不会被执行,在编译时它会使编译器感到困惑......是否有解决此类问题的方法?

最佳答案

标签分发:

template< typename T >
void AbstractEvent::setVar_impl( QString varName, T value, std::true_type /*is_ptr*/) 
{
    void * castValue = static_cast<void*>(value);
    if (castValue)
    {
            //do sth with castValue
    }
}

template< typename T >
void AbstractEvent::setVar_impl( QString varName, T value, std::false_type /*is_ptr*/) 
{
    //do something with value
}

template< typename T >
void AbstractEvent::setVar( QString varName, T value){
    setVar_impl(varName, value, std::is_pointer<T>());
}

或者,重载然后 SFINAE 去掉不适用的:

template<typename T>
typename std::enable_if<std::is_pointer<T>::value>::type 
AbstractEvent::setVar(QString varName, T value) 
{
    void * castValue = static_cast<void*>(value);
    if (castValue)
    {
            //do sth with castValue
    }
}

template< typename T>
typename std::enable_if<!std::is_pointer<T>::value>::type 
AbstractEvent::setVar( QString varName, T value) 
{
    //do something with value
}

第三种选择,直接重载:

template< typename T >
void AbstractEvent::setVar( QString varName, T* value) 
{
    void * castValue = static_cast<void*>(value);
    if (castValue)
    {
            //do sth with castValue
    }
}

template< typename T >
void AbstractEvent::setVar( QString varName, T value) 
{
    //do something with value
}

第一个模板通过部分排序比第二个模板更专业,因此如果两者同样可行,将被选中。

您可能还想对 T == nullptr_t 情况进行特殊处理。 nullptr_t 不是指针类型,但您可能希望在那种情况下调用指针重载。

关于c++ - 模板函数实现中的条件取决于类型是否为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26466729/

相关文章:

C++ 模板 : template argument error

C++ 限制输入的字符数

c++ - Boost Libraries 的使用和优于其他库的优势

带有模板参数的 C++ 函数分派(dispatch)

php - 如何在 ZF2 中渲染带有布局的邮件模板?

c# - 简单的rtsp广播示例源码

c++ - 如何使模板化运算符推断出正确的返回类型?

c++ - 指向这个定义的内部类的静态指针,用于模拟 googletest

c - TDataset --> 指向行列矩阵的指针?

c++ - 如何删除集合中的对象