c ++模板中有多个typename参数?

Jic*_*hao 14 c++ templates template-specialization

如何在c ++模板中有多个typename参数?

#ifndef _CALL_TEMP_H
#define _CALL_TEMP_H

#include <string>
#include <iostream>

template <typename Sig>
class Foo;

template <typename A, typename B>
class Foo
{
    public:
        void output() {
            std::cout << a_ << b_ << std::endl;
        }
        A a_;
        B b_;
};

template <typename A, typename B, typename C>
class Foo
{
    public:
        void output() {
            std::cout << a_ << b_ << c_ << std::endl;
        }
        A a_;
        B b_;
        C c_;
};

#endif
Run Code Online (Sandbox Code Playgroud)

用法:

int main()
{
    Foo<int ,int> doubleint;
    doubleint.a_ = 1;
    doubleint.b_ = 2;
    doubleint.output();
//  Foo<int , int , std::string> comp;
//  comp.a_ = 1;
//  comp.b_ = 2;
//  comp.c_ = "haha";
//  comp.output();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

但它不会编译.我怎么能让它编译?

Die*_*ühl 37

只需使用可变参数模板声明主模板,然后专门针对每个受支持的模板参数数量.例如:

#ifndef CALL_TEMP_H
#define CALL_TEMP_H

#include <iostream>

template <typename...> class Foo;

template <typename A, typename B>
class Foo<A, B>
{
public:
    void output() {
        std::cout << a_ << b_ << '\n';
    }
    A a_;
    B b_;
};

template <typename A, typename B, typename C>
class Foo<A, B, C>
{
public:
    void output() {
        std::cout << a_ << b_ << c_ << '\n';
    }
    A a_;
    B b_;
    C c_;
};

#endif
Run Code Online (Sandbox Code Playgroud)

我不能使用C++ 11,并且您希望保留一个类似的符号,您需要使用模板默认参数来模拟可变参数列表.这将隐含地限制模板参数的数量,但由于您无论如何都是专门设计模板,因此这种限制并不是真实的问题.

如果可以使用不同的表示法,您还可以使用看起来像函数声明的东西来实例化和专门化您的模板:

template <typename> class Foo;

template <typename A, typename B>
class Foo<void(A, B)> {
    ...
};
template <typename A, typename B, typename C>
class Foo<void(A, B, C)> {
    ...
};
...
Foo<void(int, int)>                   f2;
Foo<void(int, int, std::string)> f3;
Run Code Online (Sandbox Code Playgroud)

符号的更改是否可接受取决于您对类模板的使用.但是,与没有C++ 11的可变参数模板一样,您将无法实现理想的解决方案.

顺便说一下,不要过度使用std::endl:'\n'用来表示行尾.如果您真的想要刷新流,请使用std::flush.也是_CALL_TEMP_H标准C++库保留的名称,所有名称都以下划线后跟大写字符开头:除非有明确的权限使用它们,否则不要在自己的代码中使用这些名称(例如__FILE__,__LINE__保留但是明确允许使用它们是被授予的).