簡體   English   中英

void_t在Visual Studio 2015上失敗

[英]void_t fails on Visual Studio 2015

我不明白為什么以下測試總是因Visual Studio 2015(static_assert觸發器)而失敗:

#include <type_traits>
using namespace std;

template<class T> using try_assign = decltype(declval<T&>() = declval<T const&>());
template<class, class = void> struct my_is_copy_assignable : false_type {};
template<class T> struct my_is_copy_assignable<T, void_t<try_assign<T>>> : true_type {};

int main()
{
    static_assert(my_is_copy_assignable<int>::value, "fail");
    return 0;
}

這基本上是Walter E Brown在他的cppcon 2014演示文稿“現代模板元編程 - 概要”中對void_t的使用示例的轉錄。

重要的是要注意這個替代版本的作用,所以我不認為問題在於MSVC對表達SFINAE的不完全支持。

template<class T>
using try_assign = decltype(declval<T&>() = declval<T const&>());

template<class T>
struct my_is_copy_assignable
{
  template<class Q, class = try_assign<Q>>
  static true_type tester(Q&&);
  static false_type tester(...);
  using type = decltype(tester(declval<T>()));
};

我知道std::is_copy_assignable但我只是想更好地理解C ++不同版本中可用的各種元編程技術。 我在網上讀了幾篇關於void_t的帖子,但我仍然不明白為什么這個例子失敗了。

有趣的是,使用GCC 4.8.2它工作正常(使用CWG 1558解決方法,這與微軟的版本相同)。

它是一個已知的Visual Studio錯誤,還是我做錯了什么?

2014年CppCon上的Walter E. Brown也提到了以下分解,它允許用任意條件替換try_assign

#include <type_traits>
#include <utility>

template<class T>
using try_assign = decltype(std::declval<T&>() = std::declval <T const &>());

template<class T, template<class> class Op, class = void>
struct is_valid : std::false_type { };

template<class T, template<class> class Op>
struct is_valid<T, Op, std::void_t<Op<T>>> : std::true_type { };

template<class T>
using is_copy_assignable = is_valid<T, try_assign>;

int main()
{
    static_assert(is_copy_assignable<int>::value, "fail");
    return 0;
}

此分解與VS 2015編譯正常。現在刪除is_copy_assignable並替換為is_valid 您最終得到了您提供的代碼並且無法編譯(VS 2015)。

這表明VS 2015中存在一個錯誤,它與CWG 1558無關。在CWG問題中,標准不清楚別名模板特化中未使用的參數是否會導致替換失敗或者被忽略。

這看起來像VC ++中的SFINAE問題。 尚不支持在類模板的部分特化的模板參數中使用依賴的decltype 它應該在VS 2015 Update 1中有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM