std::enable_if 未编译(模板参数无效)
std::enable_if not compiling (invalid template argument)
我正在编写一些代码,应该接受 std::unique_ptr 并激活运算符>>在其内容上,如果指针为空,则填充指针。
我正在尝试使用 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 ) );
^
- 这里的代码有什么问题?
- 有没有更干净的写法?(除了明显的"使用 std::unique_ptr"等。
"enable_if_t"不起作用。但我认为这只是我做错了什么的延伸,即使一开始就enable_if不起作用。
我可以说有些事情非常错误,因为我还收到一条错误消息,关于运算符*被应用于一个 int......根本不应该溜进去(如果 SFINAE 正确实现)!
这里另一个有趣的问题是编译器无法识别可序列化,即使它包含在它的正上方......如果答案不是微不足道的,我会单独查找。
我正在使用QtCreator 3.4.2/Qt 5.5.0上的MinGW 4.9.2 x32进行编译。
谢谢。
编辑:请不要建议只创建这样的函数:
Archive &operator>>( Archive &in, std::unique_ptr<Serializable> &ptr)...
我必须知道发送到此函数的对象的实际类型,并且不能依赖多态性。
删除std::is_base_of<Serializable, T>::value
之前的typename
(因为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)
{
// ...
}
它应该不那么侵入性,并且导致的类型推断问题更少。
相关文章:
- std::cin >>上的参数无效
- 结果失败或多个参数无效
- 错误:一元"*"的类型参数无效(具有"int"):使用 mergesort 计算
- 错误 带有模块的一元"*"(具有"int")的类型参数无效
- 由于调用 std::condition_variable 后参数无效而导致应用程序崩溃
- MPI_Iprobe:RMA 调用中的位移参数无效
- 推力::sort_by_key上的配置参数无效
- windres 致命错误:将输出写入时:参数无效
- 一元'*'的类型参数无效(有双精度)
- C++:传递给 C 运行时函数的参数无效
- 矢量模板参数无效
- 写入 -: 参数无效 } 时出错
- winsock2:recvfrom()函数以错误10022(参数无效)结束
- 模板参数的显式指定参数无效,该参数是 constexpr
- 模板参数无效
- 调用 getter 成员时的参数无效
- 模板模板参数中的参数无效
- 方法调用中的参数无效
- POSIX 计时器:参数无效
- C++类模板是一个模板:模板参数无效