[英]C++ ambiguous template overloads
我正在尝试使用模板特化根据模板变量的值返回不同的类型。
我已经不再尝试在运行时分支,而不是在编译时使用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()
当 SFINAEd 成功时使调用模棱两可。
一种解决方案是限制具有补码条件的那个...
但是标签调度是解决问题的一种简单替代方法:
template <typename> struct Tag{};
class Test
{
public:
template <typename T>
T request() const
{
return getVal(Tag<T>{});
}
private:
float foo = 2.f;
int bar = 1;
float getVal(Tag<float>) const { return foo; }
int getVal(Tag<int>) const { return bar; }
template<typename T> void getVal(Tag<T>) = delete;
};
您可以通过专门化getVal()
很容易地做到这一点,尽管您可能过于简化了问题
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>
T getVal() {
std::cout << "T is type " << typeid(T).name() << std::endl;
throw std::bad_typeid();
}
};
// add specializations
template<>
float Test::getVal<float>() { return foo; }
template <>
int Test::getVal<int>() { return bar; }
int main() {
Test t;
int i = t.request<int>(); // don't need template keyword here
float f = t.request<float>();
}
如果您能够使用 c++17,那么使用if constexpr
和单个getVal
就更简单了
template<typename T>
auto getVal() {
if constexpr (std::is_same_v<int, T>) {
return foo;
} else if constexpr (std::is_same_v<float, T>) {
return bar;
} else {
std::cout << "T is type " << typeid(T).name() << std::endl;
throw std::bad_typeid();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.