簡體   English   中英

為什么VS2017上的get_index實現失敗?

[英]Why does this get_index implementation fail on VS2017?

Barry 為變種提供了這個華麗的get_index

template <typename> struct tag { };

template <typename T, typename V>
struct get_index;

template <typename T, typename... Ts> 
struct get_index<T, std::variant<Ts...>>
    : std::integral_constant<size_t, std::variant<tag<Ts>...>(tag<T>()).index()>
{ };

使用如下:

using V = variant<A, B, C>;
constexpr const size_t N = get_index<B, V>::value;  // 1

它在Clang(OSX)中運行良好。

但在Visual Studio 2017中, 我得到以下內容:

<source>(10): error C2039: 'index': is not a member of 'std::variant<tag<Ts>...>'
<source>(10): note: see declaration of 'std::variant<tag<Ts>...>'
<source>(11): note: see reference to class template instantiation 'get_index<T,std::variant<_Types...>>' being compiled
Compiler returned: 2

我不明白為什么。 有任何想法嗎?

(完全披露:在我的項目中我實際上使用的是mpark::variant因為我一直在使用Xcode 9,它沒有std::variant 。但是,從上面的Godbolt MCVE可以看出這會影響實現std::variant 。我確信問題出在上面的代碼中,或者在編譯器中。)

我打賭我的2美分這是一個編譯器錯誤。

我看到如果我寫在main()

std::cout << std::variant<tag<int>, tag<float>>{tag<float>{}}.index() << std::endl;

編譯器沒有抱怨。

如果我按如下方式編寫模板函數,也不會抱怨

template <typename T, typename ... Ts>
void foo ()
 { std::cout << std::variant<tag<Ts>...>(tag<T>{}).index() << std::endl; }

我從main()調用它

foo<int, long, int, long long>();

沒問題也在main()聲明以下變量

std::integral_constant<std::size_t, std::variant<tag<int>, tag<float>>(tag<float>{}).index()>  ic;

但是,如果我更改get_index如下(使用大括號進行初始化而不是圓括號)

template <typename T, typename... Ts> 
struct get_index<T, std::variant<Ts...>>
    : std::integral_constant<std::size_t, std::variant<tag<Ts>...>{tag<T>()}.index()>
 { };

編譯器抱怨但有不同的錯誤

example.cpp

(12):錯誤C2440:'初始化':無法從'初始化列表'轉換為'std :: variant ...>'

(12):注意:目標類型沒有構造函數

(13):注意:請參閱正在編譯的類模板實例化'get_index>'的引用

編譯返回:2

似乎由於我無法理解的原因,編譯器沒有在get_index看到std::variant<tag<Ts>...>作為std::variant及其所有方法。

暫無
暫無

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

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