Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.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++ 检测类型是否不可抛出交换的特性,对于msvc也是如此_C++_C++11_Templates_Visual Studio 2015_Sfinae - Fatal编程技术网

C++ 检测类型是否不可抛出交换的特性,对于msvc也是如此

C++ 检测类型是否不可抛出交换的特性,对于msvc也是如此,c++,c++11,templates,visual-studio-2015,sfinae,C++,C++11,Templates,Visual Studio 2015,Sfinae,我需要一个简单的类型特征来检测事物是否不可交换。标准库中没有,所以我写了这个。它在gcc和clang中工作,至少我在几个月的时间里没有遇到任何问题 今天我也在尝试用MSVC 2015进行编译,它给出了一个非常简洁的编译错误,我想了解一下 以下是一个MVCE: #include <utility> #include <type_traits> // Code is targetting C++11 so we have to backport this: template

我需要一个简单的类型特征来检测事物是否不可交换。标准库中没有,所以我写了这个。它在gcc和clang中工作,至少我在几个月的时间里没有遇到任何问题

今天我也在尝试用MSVC 2015进行编译,它给出了一个非常简洁的编译错误,我想了解一下

以下是一个MVCE:

#include <utility>
#include <type_traits>

// Code is targetting C++11 so we have to backport this:
template <bool b, typename V = void>
using enable_if_t = typename std::enable_if<b, V>::type;

namespace detail {
  using std::swap;

  // Need to use SFINAE for this in case there is no `swap`.
  template <typename T, typename ENABLE = void>
  struct is_nothrow_swappable : std::false_type {};

  template <typename T>
  struct is_nothrow_swappable<T, enable_if_t<noexcept(
                                   swap(*static_cast<T *>(nullptr),
                                        *static_cast<T *>(nullptr)))>>
    : std::true_type {};
} // end namespace detail

// Tests

static_assert(detail::is_nothrow_swappable<int>::value, "");
static_assert(detail::is_nothrow_swappable<std::pair<int, int>>::value, "");

struct B {};

static_assert(detail::is_nothrow_swappable<B>::value, "");

struct A {
  A() = delete;
  A(A&&) = delete;
};

static_assert(!detail::is_nothrow_swappable<A>::value, "");

int main() {}

所以我的问题有效地解决了,但问题是,为什么一个有效,另一个失败?我的尝试到底出了什么问题?如果你能解释一下,我将不胜感激。

重复这个问题?我认为这个问题与这个问题无关。错误日志末尾的几行类似,但重要的部分是第一个错误,它(似乎)说这个
noexcept
表达式不是一个常量表达式。Idk,是什么让你认为它是一个dupe呢?
noexcept
操作符执行编译时检查,如果一个表达式被声明为不抛出任何异常,则返回true。这绝对是一个恒定的表达式是的,我知道
noexcept
应该是什么意思,但我不知道的是msvc到底是怎么回事。我猜实际上并不是我的
noexcept
没有给出一个常量表达式,错误消息似乎在说,它在
std::swap
函数的
noexcept
限定符中放的是MSVC头中的任何内容<代码>注意:请参阅正在编译的函数模板实例化“void std::swap(_Ty&,_Ty&)noexcept()”的参考我不完全确定这一行的意思这可能是MSVC错误,因为编译器实例化模板时没有实际类型,然后阻塞了swap的noexcept规范(被检测为不是常量表达式)。此代码足以使MSVC失败:
使用std::swap;模板结构是可交换的:std::integral\u constant{};
Error(s):

C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\utility(49): error C2057: expected constant expression
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\INCLUDE\utility(48): note: see reference to function template instantiation 'void std::swap<T>(_Ty &,_Ty &) noexcept(<expr>)' being compiled
source_file.cpp(6): error C2039: 'type': is not a member of 'std::enable_if<false,V>'
        with
        [
            V=void
        ]
source_file.cpp(18): error C2061: syntax error: identifier 'type'
source_file.cpp(18): error C2938: 'enable_if_t<false,void>' : Failed to specialize alias template
source_file.cpp(18): error C2059: syntax error: '<end Parse>'
source_file.cpp(24): error C2338: 
source_file.cpp(25): error C2338: 
source_file.cpp(29): error C2338: 
struct do_is_nothrow_swappable
{
  template<class T>
  static auto test(int) -> std::integral_constant<bool,
    noexcept(swap(std::declval<T&>(), std::declval<T&>()))
  >;

  template<class>
  static std::false_type test(...);
};

template <typename T>
struct is_nothrow_swappable : decltype(
  do_is_nothrow_swappable::test<T>(0)
)
{};