C++ Concepts TS 会启用多参数包吗?
Will the C++ Concepts TS enable multiple parameter packs?
在 C++14 中,无法调用具有多个参数包的函数模板:
#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
。
但是,如果给定 Future
和 Incrementable
.
的适当概念,原则上这两个参数包似乎可以消除歧义
即将推出的 C++ 概念技术规范的任何功能是否会放宽这些限制并允许调用具有多个参数包的函数模板?
In C++14, it is not possible to call a function template with multiple parameter packs
正如问题评论中提到的,即使在 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
是在函数调用时显式指定的,而参数包 B
是从函数参数中推导出来的。
这表明即使使用 C++11 也可以轻松提供多个参数包,无需为此等待概念。
Concepts Lite 的约束系统位于现有模板机制之上。特别是,它不会干扰模板参数推导。 Futures
包在您的示例中是不可推导的,即使有概念也将保持不变。
However, it seems like the two parameter packs could be disambiguated in principle, given proper Concepts for Future and Incrementable.
您可能没有在这里选择最好的例子,尽管这并没有真正使您的问题的前提变得不那么有趣。你怎么看这个?
Future{Fut}
struct incrementable_future: Fut {
using Fut::Fut;
incrementable_future& operator++() { return *this; }
};
在 C++14 中,无法调用具有多个参数包的函数模板:
#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
。
但是,如果给定 Future
和 Incrementable
.
即将推出的 C++ 概念技术规范的任何功能是否会放宽这些限制并允许调用具有多个参数包的函数模板?
In C++14, it is not possible to call a function template with multiple parameter packs
正如问题评论中提到的,即使在 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
是在函数调用时显式指定的,而参数包 B
是从函数参数中推导出来的。
这表明即使使用 C++11 也可以轻松提供多个参数包,无需为此等待概念。
Concepts Lite 的约束系统位于现有模板机制之上。特别是,它不会干扰模板参数推导。 Futures
包在您的示例中是不可推导的,即使有概念也将保持不变。
However, it seems like the two parameter packs could be disambiguated in principle, given proper Concepts for Future and Incrementable.
您可能没有在这里选择最好的例子,尽管这并没有真正使您的问题的前提变得不那么有趣。你怎么看这个?
Future{Fut}
struct incrementable_future: Fut {
using Fut::Fut;
incrementable_future& operator++() { return *this; }
};