iam*_*ind 10 c++ templates initializer-list variadic-templates c++11
假设有一个接受多个字符串的函数:
void fun (const std::initializer_list<std::string>& strings) {
for(auto s : strings)
// do something
}
Run Code Online (Sandbox Code Playgroud)
现在,我有一个可变template函数说foo():
template<typename ...Args>
void foo () {
fun(???);
}
Run Code Online (Sandbox Code Playgroud)
此方法在外部称为:
foo<A, B, C, D>(); // where A, B, C, D are classes
Run Code Online (Sandbox Code Playgroud)
这些作为参数传递的类应该包含一个公共static const成员:
static const std::string value = "...";
Run Code Online (Sandbox Code Playgroud)
以下是我的问题(如何):
foo(),检查是否所有Args包含value使用
static_assertfun()给形成initializer_list; 例如
fun({A::value, B::value, ...});搜索了几个与可变参数模板及其解包相关的线程,但我仍然是这个领域的新手.非常感谢更详细的解释.
至于第二个问题,就这样做:
template<typename ...Args>
void foo () {
fun({Args::value...});
}
Run Code Online (Sandbox Code Playgroud)
该机制非常直观:您创建一个包含扩展Args::value模式的初始化列表,从而解析(在您的情况下){ A::value, B::value, C::value, D::value }.
这是一个完整的程序:
#include <string>
#include <iostream>
void fun (const std::initializer_list<std::string>& strings) {
for(auto s : strings)
{
std::cout << s << " ";
}
}
template<typename ...Args>
void foo () {
fun({Args::value...});
}
struct A { static std::string value; };
struct B { static std::string value; };
struct C { static std::string value; };
struct D { static std::string value; };
std::string A::value = "Hello";
std::string B::value = "World";
std::string C::value = "of";
std::string D::value = "Variadic Templates";
int main()
{
foo<A, B, C, D>(); // where A, B, C, D are classes
}
Run Code Online (Sandbox Code Playgroud)
这是一个实例.
至于静态断言,您可以编写一个类型特征来确定某个类型是否具有成员变量value:
template<typename T, typename V = bool>
struct has_value : std::false_type { };
template<typename T>
struct has_value<T,
typename std::enable_if<
!std::is_same<decltype(std::declval<T>().value), void>::value,
bool
>::type
> : std::true_type
{
typedef decltype(std::declval<T>().value) type;
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以这样使用它:
template<typename T>
struct check_has_value
{
static_assert(has_value<T>::value, "!");
};
template<typename ...Args>
void foo () {
auto l = { (check_has_value<Args>(), 0)... };
fun({Args::value...});
}
Run Code Online (Sandbox Code Playgroud)
以下是成功检查的实例(所有类都有value数据成员).这是一个不成功检查的实例(D调用类的数据成员values)