如何访问参数包中的第一个参数?

时间:2016-07-19 15:30:21

标签: c++ templates variadic-templates

是否可以静态地#34;展开"编译时的参数列表,在每个"展开"中使用一个参数。步?我认为可变参数模板是部分模板特化的结合方式,但是我不能让这个例子运行:

#include <iostream>

char static const text1[] = "Foo";
char static const text2[] = "FooBar";

template <char const * TEXT, unsigned int N, char const *... REST, unsigned int... Ns>
void doStuff() {
    std :: cout << TEXT << "-" << N << std :: endl;
    doStuff<REST..., Ns...>();
} 

template <char const * TEXT, unsigned int N>
void doStuff() {
    std :: cout << TEXT << std :: endl;
} 

void doStuff() {}

int main() {
    doStuff<text1,3,text2,5>();
    return 0;
}

我的预期输出为Foo-3\nFooBar-5 但是,clang ++ 3.8给了我:

error: no matching function for call to 'doStuff'
        doStuff<text1,3,text2,5>();
        ^~~~~~~~~~~~~~~~~~~~~~~~
test.cpp:7:6: note: candidate template ignored: invalid explicitly-specified argument for template
      parameter 'REST'
void doStuff() {
     ^
test.cpp:13:6: note: candidate template ignored: invalid explicitly-specified argument for template
      parameter 'N'
void doStuff() {
     ^

2 个答案:

答案 0 :(得分:2)

在C ++ 17中,您可能会执行类似

的操作
template <char const * TEXT, unsigned int N>
void doStuff() {
    std::cout << TEXT << "-" << N << std::endl;
} 

template <auto v1, auto v2, auto ... values>
void doStuff()
{
    std :: cout << v1 << "-" << v2 << std :: endl;
    doStuff<values...>();
}

目前您必须按对方打包您的值:

template<const char* S, int N>
struct pairValue {
     static constexpr const char* s = S;
     static constexpr int n = N;
};

template <typename ... Ts>
void doStuff()
{
    const int dummy[] = {0, ((std::cout << Ts::s << "-" << Ts::n << std::endl), 0)...};
    static_cast<void>(dummy); // Avoid warning for unused variable.
}

并称之为:

 doStuff<pairValue<text1, 3>, pairValue<text2, 5>>();

答案 1 :(得分:0)

您可以将它们用作参数来解决它:

#include <iostream>
#include<type_traits>

char static const text1[] = "Foo";
char static const text2[] = "FooBar";

constexpr void doStuff() {}

template <typename T, typename U, typename... O>
constexpr
std::enable_if_t<
    std::is_same<T, const char *>::value
    and std::is_same<U, int>::value
> doStuff(T str, U num, O... o) {
    std :: cout << str << "-" << num << std :: endl;
    doStuff(o...);
}

int main() {
    doStuff(text1,3,text2,5);
    return 0;
}