Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/151.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用其他函数的返回值调用重载函数_C++_Templates_C++11_Overloading - Fatal编程技术网

C++ 如何使用其他函数的返回值调用重载函数

C++ 如何使用其他函数的返回值调用重载函数,c++,templates,c++11,overloading,C++,Templates,C++11,Overloading,我有以下类层次结构: Option (abstract) ^ | +------+-------+ | | + + Something[T] Nothing 我已尝试以以下方式使用模板: template <class T> bool is_nothing(Nothing&) {return true;}; template <cla

我有以下类层次结构:

Option (abstract) ^ | +------+-------+ | | + + Something[T] Nothing 我已尝试以以下方式使用模板:

template <class T> bool is_nothing(Nothing&) {return true;};
template <class T> bool is_nothing(Something<T> &) {return false;};

请将我引向正确的方向,因为我觉得这种方法有些错误,但我不能完全指出它。

重载解析是根据参数的静态类型而不是动态(运行时)类型来完成的。调用
is\u nothing(an\u option())
时,编译器将
an\u option()
解析为返回
option&
的函数,并将尝试按照该类型而不是引用绑定的对象的类型进行解析

如果您解释了您想要解决的问题,您可能会得到一些在该语言中工作的替代设计。最简单、通用的方法,但同时也被认为是一种代码气味,我不推荐使用这种方法,就是使用RTTI信息来推断实际的类型。具体地说,
is\u nothing
的实现可以参考
选项
,并使用RTTI(
dynamic\u cast
typeid
)来确定对象的动态类型并相应地采取行动


但这是一个糟糕的设计,如果您解释在什么环境下需要它以及您真正想要解决什么,您将得到更好的选择。

您不需要两个单独的函数
Option
有一个虚拟的
nothing()
方法,因此您可以创建一个非模板函数,返回
nothing()
返回的任何内容:

bool is_nothing(Option& opt) { return opt.nothing(); }

Nothing n;
Option& an_option() { return n; }

int main(int argc,char** argv) 
{
    if (is_nothing(an_option()))
        ...

    return 0;
}
当然,当您可以直接调用
nothing()
时,这是多余的:

Nothing n;
Option& an_option() { return n; }

int main(int argc,char** argv) 
{
    if (an_option().nothing())
        ...

    return 0;
}

您的代码不应该编译,因为您正在将非常量左值引用绑定到临时对象。请发布一些真实的代码。是的,我认为你试图将你的类建模得太像Scala的选项,它的优点是能够使用反射和其他奇特的类型魔法。这里是Boost的Option类,如果您感兴趣的话,基本上,导致我产生这种想法的问题是,我希望有一个容器接口,如果对象有效,则返回对该对象的引用,否则返回空对象。下一步是让客户机能够利用动态调度来避免您提到的讨厌行为,即RTTI。为什么我想拥有自己的接口,而不是使用STD::List或Boost,因为这个代码将被用于嵌入式项目,因此我想尽可能多地保留控制和裁减外部依赖性。我不确定您是否使用了C++中使用的相同的动态调度术语,但除此之外,我会重新考虑这个设计。标准库中的容器效率很高,可能比您所能做的还要高。拥有一个包含不相关内容的容器通常是设计中一个更深层次问题的标志,生成一个空对象也不是一个好主意(如果您想要减少代码,那么返回是否找到它的函数可能比检查对象的运行时类型更有效)。谢谢大家的帮助@David Rodríguez-dribeas是的,关于我使用动态调度,你是对的。STD::清单显示未定义行为(例如Frand()在空容器上调用的事实可能会暗示,这个问题在C++中通常是不可解决的。我充分意识到,拥有一个由无关事物组成的容器是一种设计的味道。另一方面,返回值或不返回值的想法在某些地方是有用的。@bfo:它可以实现,问题是你是否想这样做。实现这一点的简单方法是使用产生指针而不是引用的访问器,如果元素不存在,则会生成空指针。但这与标准库中的设计原则背道而驰,因为它增加了所有使用的成本,包括在合同中进行调用的使用成本(仅当
!empty()
时才调用
front()
)。库级别的未定义行为是好的,不会触发它,但是如果它能够提供优势,那么在合同中允许它。不过,如果客户机希望添加一些基于返回类型的其他功能,事情就不会那么容易了。
is_nothing<int>(Nothing());
is_nothing<int>(Something<int>(4));
Nothing n;

Option& an_option() {return n;};
int main(int argc,char** argv) 
{
    is_nothing<int>(an_option());
    return 0;
}
bool is_nothing(Option& opt) { return opt.nothing(); }

Nothing n;
Option& an_option() { return n; }

int main(int argc,char** argv) 
{
    if (is_nothing(an_option()))
        ...

    return 0;
}
Nothing n;
Option& an_option() { return n; }

int main(int argc,char** argv) 
{
    if (an_option().nothing())
        ...

    return 0;
}