#include <cstdint>
#include <iostream>
#include <typeinfo>
template <typename T> void func(const T& t) requires
std::is_same_v<T, uint8_t> || std::is_same_v<T, uint16_t>
{
std::cout << "called with type " << typeid(T).name() <<std::endl;
}
int main()
{
uint8_t x = 4;
func(x); //calls uint8_t version
uint16_t y = 4;
func(y); //calls uint16_t version
int z = 6;
// func(z); compiler error, z is not right type
}
正是你所要求的。 当您开始 * 实现 * 主体时,您会发现委托给一个模板化的访问者通常更简单,然后您又回到了现有的答案(但需要相对昂贵的运行时类型决策,而不是静态决策)。 演示in compiler explorer
void func(std::variant<uint8_t, uint16_t> value)
{
std::cout << "called with type index " << value.index() << '\n';
// templated visitor
std::visit(
[](auto && val)
{
std::cout << "called with type " << typeid(val).name()
<< ", value " << val << '\n';
},
value
);
// alternatively, test each type by hand
if (std::holds_alternative<uint8_t>(value))
{
std::cout << "got uint8_t alternative " << std::get<uint8_t>(value)
<< '\n';
}
else if (std::holds_alternative<uint16_t>(value))
{
std::cout << "got uint16_t alternative " << std::get<uint16_t>(value)
<< '\n';
}
}
4条答案
按热度按时间uqxowvwt1#
这可以通过使用函数模板和SFINAE来完成,如下所示:
axkjgtzd2#
@Jason Liam正在着手解决这个问题,但是如果你想使用不同的函数,标准的重载就是答案。如果你想用一个函数来处理这两种类型,那么就把Jason的函数组合起来:
Test in compiler explorer
o3imoua43#
在C++20中,我们可以使用
requires
子句代替SFINAE来做同样的事情:qvtsj1bj4#
准确地做到这一点的唯一方法(不需要将函数模板示例化为两个函数)是使用
std::variant
(或其他一些有区别的并集)。正是你所要求的。
当您开始 * 实现 * 主体时,您会发现委托给一个模板化的访问者通常更简单,然后您又回到了现有的答案(但需要相对昂贵的运行时类型决策,而不是静态决策)。
演示in compiler explorer