比较函数模板中的 VARTYPE 和 typeid().name / typename
Compare VARTYPE and typeid().name / typename in function templates
我有以下函数模板:
template <typename TypeName>
TypeName AssignDefaultIfNull(VARIANT Variant, TypeName & Value) {
if ((Variant.vt != VT_NULL) || (Variant.vt != VT_EMPTY))
{
CComVariant CV = Variant;
if (CV.vt != TypeName) {} // << HERE I WANT TO COMPARE THOSE TWO, BUT THEY'RE DIFFERENT THINGS. >>
}
else
{
// Default Value
}
return Value;
}
有时,我使用上面的函数模板,例如:
LONG LongValue = AssignDefaultIfNull<LONG>(rcNormalPositionBottom, lpwndpl.rcNormalPosition.bottom);
我想在上面将VARIANT
的VARTYPE (vt)
与给定的TypeName
类型名进行比较,如果匹配,则对它们执行一些操作。
我尝试使用!=
运算符,但它无法比较,因为VARTYPE
是unsigned short
而TypeName
是typename
。
我也尝试过这样:
if (CV.vt != (VARTYPE)typeid(TypeName).name()) {}
但是编译器给出了一个警告:
C4302:"类型转换":从"const char*"到"VARTYPE"的截断
难道没有办法正确比较这两种类型吗?
提前谢谢。
要使用std::variant
实现类似的概念,您可以定义一个访问者,如果请求的类型未存储在变体中,则返回指定的默认值。 使用实例化函数,可以显式指定模板参数,并让模板参数推导完成繁重的工作。
需要C++17。
#include <iostream>
#include <utility>
#include <variant>
// Leave blank incomplete to prevent uninitialized variant from
// compiling.
// struct blank;
struct blank {};
using Variant = std::variant<blank,
unsigned int,
int,
unsigned long,
long
/* ... */
>;
template < typename R >
class DefaultVisitor
{
R m_r;
public:
DefaultVisitor(R const& r) : m_r(r) {}
R operator() (R const& r) { return r; }
template < typename T >
R operator() (T const&) { return m_r; }
};
template < typename R >
DefaultVisitor<R> make_default_visitor(R const& r)
{
return DefaultVisitor<R>(r);
}
int main()
{
Variant v(long{0});
Variant w;
std::cout << std::visit(make_default_visitor(long{12}), v) << 'n'; // 0
std::cout << std::visit(make_default_visitor(int{17}), v) << 'n'; // 17
}
或者,您可以使用在C++17之前可用的Boost.Variant 这应该从 C++11 开始编译。
#include <iostream>
#include <utility>
#include <boost/variant.hpp>
using Variant = boost::variant<boost::blank,
unsigned int,
int,
unsigned long,
long
/* ... */
>;
template < typename R >
class DefaultVisitor : boost::static_visitor<R>
{
R m_r;
public:
using result_type = R ; // need this to compile in C++11
DefaultVisitor(R const& r) : m_r(r) {}
R operator() (R const& r) const { return r; }
template < typename T >
R operator() (T const&) const { return m_r; }
};
template < typename R >
DefaultVisitor<R> make_default_visitor(R const& r)
{
return DefaultVisitor<R>(r);
}
int main()
{
Variant v(long{0});
Variant w;
std::cout << boost::apply_visitor(make_default_visitor(long{12}), v) << 'n'; // 0
std::cout << boost::apply_visitor(make_default_visitor(int{17}), v) << 'n'; // 17
}
相关文章:
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 为什么返回类型中需要typename?C++
- C++中"dependent name"的定义是什么?
- 将系数存储在头文件的数组中("does not name a type"错误)
- C++ assigment std::list:<typename>:itrator 在 main 中工作,但在方法中它不起作用
- 使用 'typename' 关键字将非类型视为依赖上下文中的类型
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- C++初学者:为什么我的编译器根据我的循环返回"name not found"?
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- 如何解决"'mutex' in namespace 'std' does not name a type"?
- 在这种情况下,"typename..."意味着什么?
- 在 C++ 中使用命名空间时出现"does not name a type"错误
- 已声明时"Does not name a type"错误
- 嵌套类"does not name a type"
- 为什么不需要在 C++20 中的依赖类型之前指定"typename"?
- "Cannot convert Python object argument to type '<typename>'" - 使用 Cython 包装 C++ 类时出错
- "typename"不应该只在模板函数或模板类中使用吗?
- 比较函数模板中的 VARTYPE 和 typeid().name / typename
- 在什么情况下,"name"必须以"typename"为前缀?