我有以下功能模板:
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
的{{1}}与给定的类型名VARTYPE (vt)
,如果匹配,则执行一些操作。
我尝试使用TypeName
运算符,但无法进行比较,因为!=
为VARTYPE
且unsigned short
为TypeName
。
我也尝试过这样:
typename
但编译器发出警告:
C4302:'type cast':从'const char *'截断到'VARTYPE'
有没有可能正确比较这两种类型的方法?
提前致谢。
答案 0 :(得分:2)
要使用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
}