答案 0 :(得分:7)
您始终可以将返回值作为模板。
template<typename T> T fun(int);
template<> float fun<float>(int);
template<> int fun<int>(int);
您可以在运行时动态决定调用哪个?否。
答案 1 :(得分:0)
@DeadMG提出了基于模板的解决方案,但是你可以简单地“调整”签名(可以说是模板参数的作用)。
这个想法只是添加一个伪参数:
struct Foo
{
float fun(float); // no name, it's a dummy
int fun(int); // no name, it's a dummy
};
然后执行:
int main() {
Foo foo;
std::cout << foo.fun(int()) << ", " << foo.fun(float());
}
这可以完全用作模板解决方案(即从模板方法调用),但更容易拉动:
我更喜欢避免使用函数模板特化,一般来说,与参数的专门化一样,选择正确的重载/特化的规则很棘手。
答案 2 :(得分:0)
您可以(但不应该 * )使用重载转换运算符的代理类。
让我以Dot & Cross Product Notation:
为例[...]
还有可能为dot-product和cross-product设置operator *。
假设一个基本的矢量类型(仅用于演示):
struct Vector {
float x,y,z;
Vector() {}
Vector (float x, float y, float z) : x(x), y(y), z(z) {}
};
我们观察到点积是标量,交叉积是矢量。在C ++中,我们可能会重载转换运算符:
struct VecMulRet {
public:
operator Vector () const {
return Vector (
lhs.y*rhs.z - lhs.z*rhs.y,
lhs.z*rhs.x - lhs.x*rhs.z,
lhs.x*rhs.y - lhs.y*rhs.x
);
}
operator float () const {
return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z;
}
private:
// make construction private and only allow operator* to create an instance
Vector const lhs, rhs;
VecMulRet (Vector const &lhs, Vector const &rhs)
: lhs(lhs), rhs(rhs)
{}
friend VecMulRet operator * (Vector const &lhs, Vector const &rhs);
};
只允许operator *使用struct VecMulRet,禁止复制VecMulRet(首先是偏执狂)。
运算符*现在定义如下:
VecMulRet operator * (Vector const &lhs, Vector const &rhs) {
return VecMulRet (lhs, rhs);
}
Et瞧,我们可以写:
int main () {
Vector a,b;
float dot = a*b;
Vector cross = a*b;
}
不过,这是由1999年制定的神圣标准所祝福的。
如果您在该主题中进一步阅读,您将找到一个基准测试,确认这不会导致性能损失。
如果这太难掌握,那就是一个更为实际的例子:
struct my_multi_ret {
operator unsigned int() const { return 0xdeadbeef; }
operator float() const { return 42.f; }
};
my_multi_ret multi () {
return my_multi_ret();
}
#include <iostream>
#include <iomanip>
int main () {
unsigned int i = multi();
float f = multi();
std::cout << std::hex << i << ", " << f << std::endl;
}
* 您可以,但不应该,因为它不符合最少惊喜的原则,因为它不是常见做法。不过,这很有趣。