如何专门化元组参数的函数?

时间:2015-11-15 18:19:10

标签: c++ templates c++14 variadic-templates

我有以下功能:

template <typename Functor, typename Arg>
decltype(auto) call(Functor f, Arg &&arg) { // (1)
    // ..
}

我想为argtuple时的案例创建专门化。我试过了:

template <typename Functor, typename... Args>
decltype(auto) call(Functor f, std::tuple<Args...> &&args) { // (2)
    // ..
}

它本身有效,但当两者都存在时,(1)即使参数是一个元组,也证明是更好的匹配。我正在使用clang 3.7来编译代码。

2 个答案:

答案 0 :(得分:2)

如果你想让自己不要写丑陋的SFINAE,你需要做一级间接。您也可以委托给类模板,而不是标记调度,但我更喜欢标记

private void lstEvents_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBoxItem lbi = (lstEvents.ItemContainerGenerator.ContainerFromIndex(lstEvents.SelectedIndex)) as ListBoxItem;
            ContentPresenter cp = GetFrameworkElementByName<ContentPresenter>(lbi);
            DataTemplate dt = lstEvents.ItemTemplate;
            Label l = (dt.FindName("lblEventId", cp)) as Label;
            MessageBox.Show(l.Content.ToString());   
        }

答案 1 :(得分:1)

我发现你的例子确实有效(并且vs2015同意)

http://ideone.com/dNTsrf

基本案例是通用引用,它同时包含rvalue和rvalues(和引用)。 (现场演示http://ideone.com/kCBv3d

decltype(auto) call(int &&arg) { // (1)
    std::cout << "Base case" << std::endl;
}     
decltype(auto) call(std::tuple<int> &&args) { 
    std::cout << "TTT" << std::endl;
}
/// main:   
call(std::tuple<int>{1}); // TTT
call(2);                  // Base case
std::tuple<int> ti{5};    
call(1,ti);               // Base case (as expected!)
call(1,std::move(ti));    // TTT

注意,你的重载需要r值引用(不是转发引用),所以其他任何东西(左值引用)都将使用基本情况。

据我了解,这都是超载,但Herb Sutter的这篇文章是相关的读物:http://www.gotw.ca/publications/mill17.htm