模板函数实现中的条件,具体取决于类型是否为指针
condition in template function implementation depending on whether the type is a pointer
所以我有这个模板函数。它应该在一个更复杂的结构中设置一个变量,称为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
}
}
使用这个模板函数,我想将变量"value"存储在QVariant中,然后将QVariant存储在某个地方。
如果"value"是一个指针,我想把它作为一个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);
当然,当值不是指针时,这是没有意义的。这就是我的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>());
}
或者,过载,然后清除不适用的
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
不是指针类型,但您可能希望在这种情况下调用指针重载。
简单的重载,有人吗?
template<typename T>
void AbstractEvent::setVar(QString varName, T value);
template<typename T>
void AbstractEvent::setVar(QString varName, T* value);
您也可以使用std::conditional
:来保留您的设计
typedef typename std::conditional<std::is_pointer<T>::value, void*, T>::type cast_type;
auto castValue = static_cast<cast_type>(value);
然而,使用标记调度或重载的解决方案——尽管时间更长——可能更清晰一些。
相关文章:
- SFINAE是否取决于类型推断?
- 将强制转换简化为取决于参数的类型
- cpp 模板专用化,错误说参数 1 的类型为 T,这取决于参数 T
- 编译时函数的选择取决于类型大小
- memcpy是否取决于源指针和目标指针的类型
- 如果条件取决于模板类型并且在编译时已知,是否可以保证C++编译器不会生成分支?
- 执行特定函数取决于类型
- 模板函数,其中模板参数类型取决于函数参数
- clang 拒绝具有尾随 decltype 返回类型的模板调用是否正确,具体取决于其重载之一?
- 具有尾随返回类型的通用 lambda,具体取决于 C++11 中的可变参数
- 基类数据成员类型取决于派生类
- 类型取决于模板中的条件
- ExprTK 未知变量分辨率取决于表达式类型
- 函数模板中的无效转换错误,返回值取决于其泛型类型
- C++调用具有不同签名的函数,具体取决于类型
- 通用 cout,可以是 wcout,具体取决于类型定义
- 模板函数实现中的条件,具体取决于类型是否为指针
- 不同的值取决于c++类型
- 模板函数中的默认参数值,取决于类型
- 引用全局变量的模板函数(取决于类型)