Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ std::在未编译时启用_(模板参数无效)_C++_Enable If - Fatal编程技术网

C++ std::在未编译时启用_(模板参数无效)

C++ std::在未编译时启用_(模板参数无效),c++,enable-if,C++,Enable If,我正在编写一些代码,这些代码应该接受std::unique_ptr并在其内容上激活操作符>>,如果指针为空,则填充指针 我试图通过使用SFINAE来限制不需要的调用,但是我收到了一堆关于模板参数不好的错误消息 守则: #include "serializable.h" template <class Archive, typename T> Archive &operator>>( Archive &in, std::unique_ptr<type

我正在编写一些代码,这些代码应该接受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;
}
#包括“serializable.h”
模板
存档和操作员>>(存档和输入,标准::唯一\u ptr和ptr)
{
如果(!ptr)
swap(Serializable::construct_from_stream(in));//构造一个可序列化的派生。
在>>*ptr;
返回;
}
错误:

// 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 ) );
               ^
//1
错误:模板参数1无效
存档和操作员>>(存档和输入,标准::唯一\u ptr和ptr)
^
// 2
错误:模板参数2无效
// 3
错误:在“&”标记之前应为“::”
存档和操作员>>(存档和输入,标准::唯一\u ptr和ptr)
^
// 4
错误:在“&”标记之前应该有标识符
// 5
错误:“ptr”中的成员“swap”请求,该成员为非类类型“int”
交换(Serializable::从_流(in)构造_);
^
// 6
错误:“template struct std::enable_if”的模板参数列表中参数1的类型/值不匹配
std::unique\u ptr
^
// 7
错误:“Serializable”尚未声明
交换(Serializable::从_流(in)构造_);
^
  • 这里的代码有什么问题
  • 有没有更干净的书写方法?(除了明显的“使用std::unique_ptr”等。)
“如果启用,则启用”不起作用。但我认为这只是我做错的事情的一个延伸,即使enable_一开始不起作用

我可以看出有些地方很不对劲,因为我还收到了一条关于运算符*应用于整数的错误消息。。。如果SFINAE得到了正确的实施,那么它根本就不应该滑进去

这里另一个有趣的问题是,编译器不能识别可序列化,即使它就包含在它上面。。。如果答案不是琐碎的,我将分别查找

我在QtCreator 3.4.2/qt5.5.0上使用mingw4.9.2x32进行编译

多谢各位

编辑:请不要建议仅创建如下函数:

Archive &operator>>( Archive &in, std::unique_ptr<Serializable> &ptr)...
Archive&operator>>(存档和输入,标准::唯一的\u ptr&ptr)。。。

我必须知道发送到此函数的对象的实际类型,不能依赖多态性。

std::is_base_of::value
之前删除
typename
(因为
std:is_base of::value
不是类型)并将
enable\u if
部分移出参数类型(否则,
T
将无法推断)

模板
typename std::启用\u如果<
std::是::value的_base,
档案馆&
>::类型
操作员>>(存档和输入,标准::唯一\u ptr和ptr)

删除
std::is_base_of::value
之前的
typename
(因为
std:is_base of::value
不是类型)并将
enable_if
部分移出参数类型(否则
T
将无法推断)

模板
typename std::启用\u如果<
std::是::value的_base,
档案馆&
>::类型
操作员>>(存档和输入,标准::唯一\u ptr和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)
{
    // ...
}
模板
存档和操作员>>(存档和输入,标准::唯一\u ptr和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)
{
    // ...
}
模板
使用my_enable=std::enable_if\u t;
模板
使用is_serializable=std::is_base_of;
模板
存档和操作员>>(存档和输入,标准::唯一\u ptr和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)
{
    // ...
}
模板
存档和操作员>>(存档和输入,标准::唯一\u ptr和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)
{
    // ...
}
模板
使用my_enable=std::enable_if\u t;
模板
使用is_serializable=std::is_base_of;
模板
存档和操作员>>(存档和输入,标准::唯一\u ptr和ptr)
{
// ...
}

它应该不会太打扰人,也不会给类型推断带来太多问题。

这很管用,所以+1。不过,我认为在模板参数中加入
enable\u if
更为常见。我没有想到要返回归档文件&从enable\u if将其放在参数列表之外……好东西!这很管用,所以+1。我认为这对pu来说更为常见但是,模板参数中的
enable\u if
。没有想到要从enable\u if返回归档文件并将其放在参数列表之外…好东西!哇…所以直接在模板列表中使用enable\u if作为约束是可能的,很好知道。甜美的缩短技术,谢谢:)哇。。。因此,如果直接在模板列表中使用enable_作为约束器是可能的,很高兴知道。甜酥油技术,谢谢:)