c ++返回模板函数

时间:2014-01-23 08:52:52

标签: c++ function templates

我有这种类型的功能:

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>();

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

我有办法让它发挥作用吗?因为从运行时的角度来看,我看到没有错误,只有编译器有问题。

4 个答案:

答案 0 :(得分:3)

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

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

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

你有两种选择:一种适用于你特定情况的hackish和一种通用的。

hackish正在所有reinterpret_cast<T(*)()>语句中使用return。对于正确的T brach,它将是一个无操作。其他分支永远不会在运行时执行,所以一切都会好的。

另一种解决方案是使用模板专业化。由于它是bad idea to specialise function templates,你可以使用众所周知的“委托上课”技巧:

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();
}

答案 1 :(得分:1)

template <typename T> T (*uniRndType())()
{
    //else
    ...
}

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

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

就是这样。

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

答案 2 :(得分:0)

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

解决此问题的一种方法是使用template specialization来表明每种类型的内容。

答案 3 :(得分:0)

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

但是,如果您使用模板方法的模板类,您有两种方法:

1)只需在.h文件中写入每个模板方法的实现(在你声明模板类主体的地方),而不仅仅是原型;

2)或者在.h文件中声明原型之后,您需要使用它可能接收的模板参数来设置此模板类。