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__保留但是明确允许使用它们是被授予的).