2016-09-23 52 views
9

在C++ 14,它是不可能调用具有多个参数包的函数的模板:C++ Concepts TS会启用多个参数包吗?

#include <future> 

template<class... Futures, class... Incrementables> 
void foo(Futures&... futures, Incrementables... incrementables) 
{ 
} 

int main() 
{ 
    std::future<int> a, b; 
    int x, y; 

    // ERROR 
    foo(a, b, x, y); 

    return 0; 
} 

因为其中第一参数包端部和第二个开始目前尚不清楚,这是不可能的调用foo没有附加程序员提供的信息。

然而,看起来这两个参数包原则上可以消除歧义,给出FutureIncrementable的正确概念。

即将到来的C++概念技术规范的任何特性是否会放宽这些限制并允许调用具有多个参数包的函数模板?

+4

事实上,即使在C++ 14中,只要可以推导出这些包,也是可能的。 – skypjack

回答

5

Concepts Lite的约束系统位于现有模板机构之上。特别是,它不会干扰模板论证扣除。在你的例子中,Futures包是不可扣除的,即使有概念也是如此。

然而,似乎这两个参数包原则上可以被消除歧义,给予适当的未来和增量概念。

你可能没有选择最好的例子,尽管这并不能真正让你的问题的前提变得不那么有趣。你对此有何看法?

Future{Fut} 
struct incrementable_future: Fut { 
    using Fut::Fut; 

    incrementable_future& operator++() { return *this; } 
}; 
+0

感谢您的回答,我同意您的'incrementable_future'情况不明确。对于任何两个不相互排斥的概念,似乎可以构造一个模糊性。 –

+0

是否有可能创建一个sep_t类型并让这些包遵循NoSeps概念。 – emsr

3

在C++ 14,它不是可调用多个参数的函数模板包

正如评论的问题提到的,这是可能的,即使在C++ 14中,只要这些包可以推断。
它遵循最小,工作示例:

#include <tuple> 
#include<functional> 

template<class... T, std::size_t... I, typename... U> 
void foo(std::tuple<T...> ts, std::index_sequence<I...>, std::tuple<U...> us) 
{ } 

int main() { 
    foo(std::make_tuple(42, 'b'), std::make_index_sequence<10>(), std::make_tuple(0., 'c')); 
    return 0; 
} 

另一种方式来做到这一点是模板专门化的手段:

template<typename, typename> 
struct S; 

template<typename R1, typename... A1, typename R2, typename... A2> 
struct S <R1(A1...), R2(A2...)> {}; 

int main() { 
    S<void(int, char), int(char, float, double)> s; 
} 

这里是不需要std::tuple或第三个例子其他一些神器:

template<typename... A, typename... B> 
void f(B...) { } 

int main() { 
    f<int, char>(42, 0.); 
} 

这里的窍门是一个事实,即参数包A是EXP在函数调用中合法指定,而参数包B是从函数参数中推导出来的。

这表明,即使使用C++ 11,您也可以轻松提供多个参数包,无需等待这些概念。

+0

谢谢你提到元组技巧!我想我应该以不同的方式表达这个问题。我感兴趣的是问题的一般形式是否存在或将要解决,其中函数参数本身是可变参数。 –

+1

@JaredHoberock让我在几分钟内为此制定另一个例子。 – skypjack

+1

@JaredHoberock增加了另外几个例子。希望那些可以帮助你。 – skypjack