在编译时确定模板化函数的结果类型?

时间:2010-07-06 22:04:15

标签: c++ templates

我不确定这是可能的,但有没有办法,使用模板编程魔术,根据输入的内容定义一个具有不同返回值的函数?

潜在:

template<typename resultType>
resultType GetResult(const std::string &key); // where the value of key may change resultType

template<typename keyType, typename resultType>
resultType GetResult(keyType key);

现在,我知道上述情况并不正确。要使用第一个,您必须在调用函数之前知道resultType是什么。但是,我已经了解到,只需另一层(或两层)间接即可实现许多“不可能”的事情。我似乎无法找到正确的方法。

第二种选择让我的大脑感到震惊。我觉得我应该能够定义一些将字符串映射到类型(或其他)的其他辅助对象,然后编译时结果将使用适当的模板参数调用GetResult

编辑:假设用于resultType的类型不相关。没有可以针对“真实”类型进行测试的界面(可能是intMyClass *)。

编辑2:真实世界的用法是我有一个包含Widgets,Gadgets等集合的第三方对象。您可以通过字符串id(方便地以前缀为前缀)来请求这些,但你必须解析字符串以找出你需要调用“collectionInstance.getWidget(id)”。我的计划是编写一个薄的包装器对象,它将智能地知道如何获取这些内部对象。

4 个答案:

答案 0 :(得分:2)

您需要一个辅助元函数,它将在第二个示例中映射这些类型。然后typename helper<keyType>::type将成为您的返回类型,并且将删除keyType模板参数。您的帮助器元函数需要根据其模板参数创建type typedef。您可以找到boost :: mpl :: map这个任务的有用实用程序,可能还有BOOST_STRONG_TYPEDEF来定义基于std :: string的不同类型。

答案 1 :(得分:2)

没有。您无法使在编译时定义的返回类型取决于运行时值。

你可以返回boost :: variant或boost :: any。

答案 2 :(得分:0)

根据您的编辑,您想要的不是您想要的。你需要的是:

1)在X,Y,Z无关类型中存储任何类型的变量的方法。 2)一种解析字符串以找出要调用哪个函数以获取变量的方法。

第一个可以用boost :: variant解决。

第二种可以通过两部分解决方案来解决。首先是解析例程,它返回一个实际进行适当调用的函数或对象。第二个是进行此调用并分配给变量的一组对象或函数。因此,你最终会得到类似的东西:

boost::variant<X,Y,Z> get_result(std::string stuff)
{
    return parser::instance().get_call(stuff).make_call(stuff);
}

如果您确实需要将类型信息与字符串的其余部分分开,那么get_call将需要为您执行此操作,或者您需要另一个函数将字符串分成两部分,然后您将其提供给上述调用。

答案 3 :(得分:0)

你可以使用强制转换操作符来破解它。我没有声称这是一个很好的编程实践,但它是可行的:

    template <typename keyType>
    class GetResult
    {
      keyType mkey;

      GetResult(keyType key) : mkey(key) {}

      template <typename resultType>
      operator resultType()
      {
           //do stuff here that returns result type
      }
    }