我们可以在基类中声明一个具有相同签名但返回类型不同的函数吗
Can we declare a function with the same signature but different return type in the base class?
这个问题可能看起来很傻,但我想问。。有没有什么方法可以在一个类中声明一个具有相同签名但不同返回类型的方法(如int fun(int(和float fun(int((,在创建对象的过程中,我们可以动态决定执行哪个函数!我有编译错误。。。有没有其他方法可以实现这个逻辑可以使用模板。。。
您可以始终将返回值作为模板。
template<typename T> T fun(int);
template<> float fun<float>(int);
template<> int fun<int>(int);
你能在运行时动态地决定调用哪个吗?编号
@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());
}
这可以完全用作模板解决方案(即从模板方法调用(,但更容易提取:
- 不那么冗长
- 函数模板专用化应该在类之外定义(尽管VC++将接受类中的内联定义(
我更喜欢避免函数模板的专门化,一般来说,就像参数的专门化一样,选择正确重载/专门化的规则很棘手。
您可以(但不应该(使用重载转换运算符的代理类。
带有实际用例的长示例*
让我以Dot&交叉乘积符号:
[…]
点积和叉积都有运算符*的可能性。
假设一个基本矢量类型(仅用于演示(:
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);
};
只允许运算符*使用结构VecMulRet,禁止复制VecMulRets(偏执狂优先(。
操作员*的定义如下:
VecMulRet operator * (Vector const &lhs, Vector const &rhs) {
return VecMulRet (lhs, rhs);
}
瞧,我们可以写:
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;
}
*你可以,但不应该,因为这不符合最小惊喜的原则,因为这不是常见的做法。尽管如此,这还是很有趣的。
相关文章:
- 如何获取std::result_of函数的返回类型
- 如何建立使用模板函数的lambda函数的尾部返回类型
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 函数作为模板参数,是否对返回类型强制约束
- C++中函数的向量返回类型引发错误
- 检查函数返回类型是否与STL容器类型值相同
- 警告:在函数返回类型 [-Wignore 限定符] 时忽略类型限定符
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 为什么返回类型的'const'限定符对标有 __forceinline/内联的函数没有影响?
- 在 c++ 中将函数返回类型指定为模板参数
- 使用 SWIG 更改生成的 CS 函数中的返回类型
- C++ 这里有一个返回 (24) 的布尔返回类型函数
- 使用SFINAE来检测void返回类型函数的存在
- 模板返回类型函数如何在C++中工作
- 如何在返回类型函数模板的专用化中使用派生类型?( "couldn't infer template argument" )
- Bon appetit :从 int 返回类型函数在 main() 中打印字符串
- 在引用或指针返回类型函数上输入
- 在后面的返回类型函数语法中,auto关键字背后是否有意图
- 我可以在c++中重写字符串返回类型函数吗?