匹配模板类中的CRTP
最近我一直在摆弄模板并偶然发现了以下问题。我正在实现这样的 CRTP 模式:
template<typename derived_t>
struct protocol_object
{
...
};
struct data_object : public protocol_object<data_object>
{
...
};
我现在想在成员模板函数中匹配 class protocol_object
的实例,同时仍然接受非 CRTP 类型:
struct consumer_impl
{
template<typename derived_t>
void match(protocol_object<derived_t> &value)
{
std::cout << "protocol_class";
};
template<typename T>
void match(T &value)
{
std::cout << "any other type";
};
}
不幸的是,只调用了第二个版本。显然,不考虑或拒绝 match(protocol_object
,而是采用更通用的 match(T &value)
形式。
data_object object;
double value;
consumer_impl consumer;
consumer.match(value); // yields "any other type" OK
consumer.match(object); // also yields "any other type" but want "protocol_class"
有办法解决这个问题吗?
感谢您的任何提示。 阿内
lately I've been toying around with templates and stumbled upon the following problem. I am implementing the CRTP pattern like this:
template<typename derived_t>
struct protocol_object
{
...
};
struct data_object : public protocol_object<data_object>
{
...
};
I now would like to match instances of class protocol_object
in a member template function, while still accepting non CRTP-types:
struct consumer_impl
{
template<typename derived_t>
void match(protocol_object<derived_t> &value)
{
std::cout << "protocol_class";
};
template<typename T>
void match(T &value)
{
std::cout << "any other type";
};
}
Unfortunately only the second version is ever called. Apparently match(protocol_object<derived_t> &value)
is not considered or rejected in favour of the more general form match(T &value)
.
data_object object;
double value;
consumer_impl consumer;
consumer.match(value); // yields "any other type" OK
consumer.match(object); // also yields "any other type" but want "protocol_class"
Is there a way out of this?
Thanks for any hints.
Arne
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这与 CRTP 无关。这是以下情况的一般情况:
问题是
T& value
是Derived&
的精确匹配,而Base&
是不精确匹配。因此,我们将使通用形式变得更差:现在,需要向上转型的专业化比需要用户定义转换的通用模板更好匹配。
This isn't related to CRTP. It's a general case of the following:
The issue is that
T& value
is an exact match forDerived&
, whileBase&
is an inexact match. So we shall make the general form a worse match:Now the specialization, requiring an upcast, is a better match than the general template, requiring a user-defined conversion.
重载解析是基于静态类型执行的,因为它是编译时编译器的决定。试试这个:
Overload resolution is performed based on the static type, since it is a compile-time compiler decision. Try this:
第二个函数是更好的匹配,因为它不需要转换,而第一个函数需要派生到基的转换。
您可以使用 boost 来克服这个问题:
这适用于从
protocol_object
派生的所有类T
,但不适用于protocol_object
本身。您可以为其添加另一个重载(基本上,重用您的第一个match
函数),或者修改enable_if
中的条件,使其匹配protocol_object
代码>也是。The second function is a better match, as no conversion is required for it, whereas the first function requires a derived-to-base conversion.
You can use boost to overcome this:
This will work for all classes
T
derived fromprotocol_object<T>
, but not forprotocol_object<T>
itself. You can add another overload for it (basically, reuse your firstmatch
function), or modify the condition inenable_if
so that it matchesprotocol_object<T>
too.