![](/img/trans.png)
[英]No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
[英]SFINAE User-Defined-Conversion Operator
我正在尝试使用自省设计的模板化用户定义转换。
在 C++20 中,我可以执行以下操作:
template<typename T>
operator T() const
{
if constexpr( requires { PFMeta<T>::from_cursor(*this); } )
{
return PFMeta<T>::from_cursor(*this);
}
else
{
T x;
std::memcpy(&x, &data, sizeof(x));
return x;
}
}
即,如果PFMeta<T>::from_cursor(const struct PFCursor&)
则使用它,否则执行 memcpy。 (godbolt 中的更长示例: https://godbolt.org/z/abed1vsK3 )
我喜欢这种方法,但不幸的是,这个库也需要在 C++17 上工作。
所以我一直在尝试将 SFINAE 作为概念的替代方案,但这非常棘手。 我终于设法得到类似的东西,但使用模板化方法as
不是用户定义的转换运算符本身:
template<typename T, typename = void>
struct has_from_cursor : std::false_type { };
template<typename T>
struct has_from_cursor<T, decltype( PFMeta<T>::from_cursor(std::declval<struct PFCursor>()), void() ) > : std::true_type { };
// ...
template<class T>
std::enable_if_t<has_from_cursor<T>::value, T> as() const
{
return PFMeta<T>::from_cursor(*this);
}
template<class T>
std::enable_if_t<!has_from_cursor<T>::value, T> as() const
{
T x;
std::memcpy(&x, &data, sizeof(x));
return x;
}
我尝试了以下编译但不起作用的方法(我无法使用它):
template<typename T>
operator std::enable_if_t<has_from_cursor<T>::value, T>() const
{
return PFMeta<T>::from_cursor(*this);
}
template<typename T>
operator std::enable_if_t<!has_from_cursor<T>::value, T>() const
{
T x;
std::memcpy(&x, &data, sizeof(x));
return x;
}
更长的例子: https://godbolt.org/z/5r9Mbo18h
所以两个问题:
enable_if
更简单的方法来执行as
方法? 理想情况下,我想做一些事情,比如定义默认的模板化方法,然后在条件存在时有一个首选的专业化(即有一个元 class 和一个 static 成员 ZC1C425268E68385D1AB5074C17A 定义)谢谢!
对于用户定义的转换运算符,我可以有效地使用 C++17 中的 SFINAE 来有效地处理概念吗?
if constepr
考虑 C++17 支持。 鉴于您已经开发了从std::true_type
或std::false_type
false_type 继承的has_from_cursor
自定义类型特征,您可以将它用于if constexp
。
我的意思是(注意:代码未经测试)
template<typename T>
operator T() const
{ // .............VVVVVVVVVVVVVVVVVVVVVVVVV
if constexpr( has_from_cursos<T>::value )
{
return PFMeta<T>::from_cursor(*this);
}
else
{
T x;
std::memcpy(&x, &data, sizeof(x));
return x;
}
}
有没有比类型特征和 enable_if 更简单的方法来执行 as 方法? 理想情况下,我想做一些事情,比如定义默认的模板化方法,然后在条件存在时有一个首选的专业化(即有一个元 class 和一个 static 成员 ZC1C425268E68385D1AB5074C17A 定义)
我想你可以尝试标签调度......
我的意思是从operator T()
中调用 'as()' 并带有一个额外的int
参数
template<typename T>
operator T() const
{ return as<T>(0); } // <-- call as() with a int
其中有一个特定于from_cursos
class 的as()
,它接收未使用的int
并且只是通过decltype()
启用/禁用 SFINAE
template <typename T> // ........accept an int; best match
decltype(PFMeta<T>::from_cursor(*this)) as (int) const
{ return PFMeta<T>::from_cursor(*this); }
和一个通用as()
,接收很long
template <typename T>
T as (long) const // <-- accept a long; worst match
{
T x;
std::memcpy(&x, &data, sizeof(x));
return x;
}
诀窍是未使用的参数:一个int
。
当启用专用as()
时,如果首选,因为接受int
所以是更好的匹配。
当专用as()
被禁用时,将通用as()
保持为比没有更好的匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.