假设我们有一个班级:
template <class Type>
class A
{
public:
void function1(float a, Type b);
void function1(float a, float b);
};
现在实例化这样的类:
A<int> a;
没关系,这个类将有2个带有这些参数的重载函数:(float a,int b); (浮动a,浮动b);
但是当你像这样实例化这个类时:
A<float> a;
您收到编译错误:
成员函数已重新声明。
所以,根据Type的类型,我不想(或者不想)编译器定义一个函数,如下所示:
template <class Type>
class A
{
public:
void function1(float a, Type b);
#if Type != float
void function1(float a, float b);
#endif
};
但是,当然,上面的语法不起作用。是否可以在C ++中执行这样的任务?如果可能,请举例说明。
答案 0 :(得分:9)
您可以使用一些C++11
std::enable_if
:
template <class Type>
class A
{
public:
template<typename t = Type,
typename std::enable_if<!std::is_same<t, float>::value, int>::type = 0>
void function1(float a, Type b) {
}
void function1(float a, float b) {
}
};
答案 1 :(得分:8)
您可以使用模板专业化:
template <class Type>
class A {
public:
void function1(float a, Type b) {
}
void function1(float a, float b) {
}
};
template <>
class A<float> {
public:
void function1(float a, float b) {
}
};
// ...
A<int> a_int;
a_int.function1(23.4f, 1);
a_int.function1(23.4f, 56.7f);
A<float> a_float;
a_float.function1(23.4f, 56.7f);
如果您有大量常用功能,可以执行以下操作:
class AImp {
public:
void function1(float a, float b) {
}
void function1(float a, double b) {
}
void function1(float a, const std::string& b) {
}
// Other functions...
};
template <class Type>
class A : public AImp {
public:
void function1(float a, Type b) {
}
using AImp::function1;
};
template <>
class A<float> : public AImp {
};
// ...
A<int> a_int;
a_int.function1(23.4f, 1);
a_int.function1(23.4f, 56.7f);
a_int.function1(23.4f, 56.7);
a_int.function1(23.4f, "bar");
A<float> a_float;
a_float.function1(23.4f, 56.7f);
a_float.function1(23.4f, 56.7);
a_float.function1(23.4f, "bar");
答案 2 :(得分:2)
使用SFINAE:
#include <iostream>
#include <type_traits>
template <typename Type>
struct Foo {
template <typename T = Type>
void function1(float a, float b, typename std::enable_if<!std::is_same<T, float>::value>::type *c = 0) {
std::cout << "float\n";
}
void function1(float a, Type b) {
std::cout << "type\n";
}
};
int main() {
Foo<float> f;
f.function1(1, 1);
f.function1(1.0f,1.0f);
Foo<int> g;
g.function1(1,1);
g.function1(1.0f,1.0f);
g.function1(1.0,1.0); // warning!
}
输出:
type
type
type
float
type
您需要C ++ 11模式,以允许功能模板中的默认模板参数。而且要获得enable_if
和is_same
,尽管您可以从Boost获得enable_if
。
“警告!”是因为原始代码g.function1(1.0,1.0);
含糊不清。现在,非模板重载是首选。你可以通过
template <typename T = Type>
void function1(float a, Type b, typename std::enable_if<true>::type *c = 0) {
std::cout << "type\n";
}