【发布时间】:2019-02-13 18:08:17
【问题描述】:
我正在尝试使用模板特化来根据模板变量的值返回不同的类型。
我已经不再尝试在运行时分支,而不是在编译时使用typeof()、非专业模板和使用std::enable_if_t<>。我认为这可能源于对模板函数的解析方式缺乏了解。
class Test
{
public:
template <typename T>
T request()
{
T ret = getVal<T>();
return ret;
}
private:
float foo = 2.f;
int bar = 1;
template <typename T>
typename std::enable_if<std::is_same<T, float>::value, bool>::type
getVal() { return foo; }
template <typename T>
typename std::enable_if<std::is_same<T, int>::value, bool>::type
getVal() { return bar; }
template<typename T>
T getVal()
{
std::cout << "T is type " << typeid(T).name() << std::endl;
throw std::bad_typeid();
}
};
int main()
{
Test t;
int i;
float f;
i = t.template request<int>();
f = t.template request<float>();
}
我希望这可以解决三个不同的功能,但我不确定是不是这样:
T Test::getVal()
int Test::getVal()
float Test::getVal()
任何帮助将不胜感激。
【问题讨论】:
-
为什么不使用普通的模板特化?像下面这样的东西可能会起作用:
template<typename T> T getVal(){ /* default impl */ } ... template<> int getVal<int>(){ return bar; } ... template<> float getVal<float>(){ return foo; } -
您将在这里遇到的一个问题是
getVal<int>将匹配getVal的第二个和第三个声明,并且会模棱两可。你在这里的最终目标到底是什么?如果问题只是出于好奇,这是使用模板的非常不寻常的方式,更好的示例可能有助于更好地理解。 -
我认为这个问题不能完全回答同一个问题,因为
GC::Allocate<A>在这种情况下成功解决,而Test::request<int>()在这里没有解决。在这种情况下,将附加参数传递给函数的解决方案没有帮助,因为目标是从另一个类的初始化程序列表中的 Test 获取值。虽然这超出了示例的范围 -
要解决模棱两可的问题,您需要将最后一个版本更改为仅适用于不是
int或float的类型。以typename std::enable_if<!std::is_same<T, int>::value && !std::is_same<T, float>::value, bool>::type getVal为例。 -
“虽然这超出了示例的范围”,但并非如此。你想通过这段代码实现什么是完全相关的,只有当你告诉我们你想实现什么时,我们才能告诉你如何实现它,只是修复编译器错误永远不会导致代码干净
标签: c++ templates template-specialization