通过模板元编程生成模板特化。奇怪的编译器行为

时间:2015-12-02 07:39:03

标签: c++ templates c++11 template-meta-programming

源代码

这基本上是一种非递归的<Grid> <Grid.Resources> <FrameworkElement x:Key="ProxyElement" DataContext="{Binding}"/> </Grid.Resources> <ContentControl Visibility="Collapsed" Content="{StaticResource ProxyElement}"></ContentControl> <DataGrid x:Name="dataGridsupplier" ItemsSource="{Binding Collection}" AutoGenerateColumns="False"> <DataGrid.Columns> <DataGridTextColumn Header="Full Company Name" Binding="{Binding fullCompanyName, UpdateSourceTrigger=PropertyChanged}" Width="*"/> <DataGridComboBoxColumn Header="Payment Method" ItemsSource="{Binding DataContext.Method, Source={StaticResource ProxyElement}}" SelectedItemBinding="{Binding methodOfPayment}"/> </DataGrid.Columns> </DataGrid> </Grid> 实现。

注意:要使此非递归,必须使用非递归实现替换std::tuple_element。我用std::make_index_sequence留下它以提供MVCE。

std::make_index_sequence具有deduct<std::size_t, T>的特化,它是从它接收的索引序列模板参数生成的。它用于在可变参数类型模板或元组中推导出deduct_impl<T>处的类型。

indexitp<std::size_t>是一个索引类型对,用于使用类型可变参数模板扩展可变参数索引模板,以匹配生成的特化。

itp<std::size_t, T>通过使用deducer<std::size_t, T...>专门化deduct<std::size_t, T>deduct_impl<T>来生成正确的专业化,从而将所有内容放在一起。

基本上,对于std::conditional_t,为了获得索引1处的类型,它会创建std::tuple<void, int, char>并将其传递给itp_base<0>, itp<1, int>, itp_base<2>deduct

deduct_impl

奇数编译器行为

锵++

我收到来自Clang ++的不可删除模板参数的警告,但程序输出正确。

Visual C ++ v140

正确检测到类型。但是我得到以下警告:

#include <iostream> #include <string> #include <tuple> template <std::size_t index> struct itp_base {}; template <std::size_t index, typename T> struct itp : itp_base<index> {}; template <std::size_t index, typename IndexSequence> struct deduct; template <std::size_t index, std::size_t... indices> struct deduct<index, std::index_sequence<indices...>> { template <typename Tuple> struct deduct_impl; template <typename T, typename... R> struct deduct_impl<std::tuple<itp_base<indices>..., itp<index, T>, R...>> { using type = T; }; }; template <std::size_t index, typename... Types> class deducer { private: static_assert( index < sizeof...( Types ), "deducer::index out of bounds" ); template <typename IndexSequence> struct deducer_impl; template <std::size_t... indices> struct deducer_impl<std::index_sequence<indices...>> { using type = typename deduct<index, std::make_index_sequence<index> >::template deduct_impl < std::tuple < std::conditional_t < std::is_base_of<itp_base<indices>, itp<index, Types>>::value, itp<index, Types>, itp_base<indices> >... > >::type; }; public: using type = typename deducer_impl< std::make_index_sequence<sizeof...( Types )>>::type; }; template <std::size_t index, typename... Types> using tuple_element_t = typename deducer<index, Types...>::type; int main() { tuple_element_t<3, int, void, char, std::string> s{ "string" }; std::cout << s << '\n'; }

该程序不输出任何内容。

G ++

一切正常。

演示

http://coliru.stacked-crooked.com/a/7cb3ac06ab4b2d4c

0 个答案:

没有答案