繁体   English   中英

C ++返回模板函数

[英]c++ return template function

我有这种功能:

type uniRndtype()
{
    return typeValue;
}

现在我试图将它们包装在另一个模板函数中,如下所示:

template<typename T>
T(* uniRndType(void))()
{
    if (is_same<T, bool>::value)
    {
        return uniRndBool;
    } else if (is_same<T, char>::value)
    {
        return uniRndChar;
    } else
    ...
}

并这样称呼它:

uniRndType<int>();

但是我遇到一个错误: “错误:返回值类型与函数类型不匹配”,因为每个返回都具有不同的类型。

我有办法使其工作吗? 因为从运行时的角度来看,我看不到任何错误,所以只有编译器才有问题。

问题在于,尽管优化器可以消除无效的代码分支,但前端(词法,句法和语义分析)却无法。 这意味着模板实例中的所有代码都必须有效。 也就是说,即使在此情况下:

if (is_same<T, bool>::value)
{
    return uniRndBool;
}

Tchar ,body将永远不会执行,它仍然必须是有效的C ++代码。 当然不是,因为uniRndBool没有正确的类型。

您有两种选择:一种在您的特定情况下有效的朴拙的选择,另一种是通用的。

拙劣的做法是在所有return语句中使用reinterpret_cast<T(*)()> 对于正确的T分支,将不进行操作。 其他分支永远不会在运行时执行,因此一切都会好起来的。

另一种解决方案是使用模板专门化。 由于专门设计函数模板不是一个好主意 ,因此可以使用众所周知的“委托给类”技巧:

template <class T>
struct uniRndTypeHelper;

template <>
struct uniRndTypeHelper<bool>
{
  static bool (*get())() { return uniRndBool; }
};

template <>
struct uniRndTypeHelper<char>
{
  static char (*get())() { return uniRndChar; }
};

template<typename T>
T(* uniRndType(void))()
{
  return uniRndTypeHelper<T>::get();
}
template <typename T> T (*uniRndType())()
{
    //else
    ...
}

template <> bool (*uniRndType())()
{
    return uniRndBool;
}

template <> char (*uniRndType())()
{
    return uniRndChar;
}

就这样。

编辑:原则上,我们必须像@Angew。 但是有点麻烦

这是行不通的,因为当编译器将模板方法扩展为给定类型时,该方法必须有效。 您的类型T必须与列出的所有返回类型兼容,例如boolchar等。正如我在评论中所提到的,如果您传入了std::string您不会期望该方法起作用,您?

解决此问题的一种方法是使用模板特化指示每种类型的需求。

编译器需要知道在编译时函数/方法将使用哪种类型。 此时,您必须使用可以作为模板参数接收的类型实例化此模板函数,例如@ikh在此处编写的。

但是,如果将模板类与模板方法一起使用,则有两种方法:

1)只需将每个模板方法的实现写在.h文件中(就在声明模板类主体的位置),而不是仅使用原型;

2)或在.h文件中声明原型后,您需要使用可能会收到的模板参数来实例化此模板类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM