[英]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.