[英]std::enable_if not compiling (invalid template argument)
我正在编写一些应接受std :: unique_ptr并在其内容上激活operator >>的代码,如果该指针为空,则填充该指针。
我试图通过使用SFINAE来限制不必要的调用,但是我收到了一堆关于模板参数错误的错误消息。
编码:
#include "serializable.h"
template <class Archive, typename T>
Archive &operator>>( Archive &in, std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, T>::type> &ptr )
{
if ( !ptr )
ptr.swap( Serializable::construct_from_stream( in ) ); // Constructs a Serializable derivative.
in >> *ptr;
return in;
}
错误:
// 1
error: template argument 1 is invalid
Archive &operator>>( Archive &in, std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, T>::type> &ptr )
^
// 2
error: template argument 2 is invalid
// 3
error: expected '::' before '&' token
Archive &operator>>( Archive &in, std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, T>::type> &ptr )
^
// 4
error: expected identifier before '&' token
// 5
error: request for member 'swap' in 'ptr', which is of non-class type 'int'
ptr.swap( Serializable::construct_from_stream( in ) );
^
// 6
error: type/value mismatch at argument 1 in template parameter list for 'template<bool <anonymous>, class _Tp> struct std::enable_if'
std::unique_ptr<typename std::enable_if<typename std::is_base_of<Serializable, T>::value, Serializable>::type>
^
// 7
error: 'Serializable' has not been declared
ptr.swap( Serializable::construct_from_stream( in ) );
^
“ enable_if_t”不起作用。 但是我认为这只是我做错了什么的扩展,甚至使enable_if最初都不起作用。
我可以说是很不对劲,因为我还收到一条关于将operator *应用于int的错误消息……这根本不应该放进内部(如果SFINAE正确实现)!
这里的另一个有趣的问题是,即使编译器位于其上方,编译器也无法识别Serializable。如果答案不重要,我将单独对其进行查找。
我正在QtCreator 3.4.2 / Qt 5.5.0上使用MinGW 4.9.2 x32进行编译。
谢谢。
编辑:请不要建议只创建一个像这样的函数:
Archive &operator>>( Archive &in, std::unique_ptr<Serializable> &ptr)...
我必须知道发送给此函数的对象的实际类型,并且不能依赖多态性。
移除typename
之前std::is_base_of<Serializable, T>::value
(因为std:is_base_of<...>::value
不是一个类型)并移动enable_if
部出来的参数类型(否则T
不会可推论的)。
template <class Archive, typename T>
typename std::enable_if<
std::is_base_of<Serializable, T>::value,
Archive &
>::type
operator>>( Archive &in, std::unique_ptr<T> &ptr )
进行SFINAE的最佳方法和较不麻烦的一种方法是使用非类型模板参数:
template <class Archive, typename T,
std::enable_if_t<std::is_base_of<Serializable, T>::value, int> = 0
>
Archive &operator>>( Archive &in, std::unique_ptr<T>& ptr)
{
// ...
}
如果要缩短它:
template<typename Cond>
using my_enable = std::enable_if_t<Cond::value, int>;
template<typename T>
using is_serializable = std::is_base_of<Serializable, T>;
template <class Archive, typename T, my_enable<is_serializable<T>> = 0>
Archive &operator>>( Archive &in, std::unique_ptr<T>& ptr)
{
// ...
}
它应该减少干扰,并减少类型推导的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.