通过模板包扩展混合类型名称和值

Mixing typenames and values with template pack expansion

本文关键字:类型 混合 扩展 包扩展      更新时间:2023-10-16

使用模板包扩展时是否可以混合使用类型名称和值?

例如,是否可以执行类似于下面的 Bar 函数的操作?

template <typename T> class A
{
public:
    void Foo()
    {
        printf( "A.Foo()n" );
    }
};
template <typename T, int x> class B
{
public:
    void Foo()
    {
        printf( "B.Foo() with x = %dn", x );
    }
};
template <typename ClassType, typename... SubVals>
void Bar( ClassType<SubVals...> obj )
{
    obj.Foo();
}
int main(int argc, char** argv)
{
    A<int> a;
    B<float, 3> b;
    Bar<int>( a ); // This is allowed by the compiler
    Bar<float, 3>( b ); // Compiler yells at this, though.
    return 0;
}

您可以通过接受 int 的非类型参数包来解决这个问题,并让编译器为在类型和零个或多个int值上模板化的类推导出第三个模板参数。

template<typename T, int... Vals, template<typename, int...> class C> 
void Bar(C<T, Vals...> obj)
{
    obj.Foo();
}

可以使用显式模板参数调用,如示例中所示:

A<int> a;
B<float, 3> b;
C<double, 1, 2, 3> c;
// explicit template args
Bar<int>(a);
Bar<float, 3>(b);
Bar<double, 1, 2, 3>(c);

或推断的:

// deduced ones
Bar(a);
Bar(b);
Bar(c);

现场演示(注意我留下了早期的工作原型,对于某些人来说可能更容易遵循)。