我的目标是编写一个函数:
Tuple表示任意 std::tuple的模板参数Match表示要测试的类型的模板参数我在 GCC 10.2 上,如果需要,我可以升级。我也可以切换到 Clang。我避免使用 Boost,但也开始觉得将其包含在我的项目中是不可避免的。
如果 C++20 允许idx变量作为编译时常量,我就完成了。但是,这并没有使其成为标准:
template<typename Tuple, typename Match>
consteval bool tuple_holds()
{
constexpr std::size_t size = std::tuple_size<Tuple>::value;
constexpr auto all = std::ranges::iota_view{std::size_t{0}, size};
for (const auto idx : all) {
// This doesn't work, as idx is not available as a compile-time constant
using Type = std::tuple_element<idx, Tuple>::type;
if (std::is_same<Type, Match>::value) {
return true;
}
}
return false;
}
using A = std::tuple<float, int>;
int main()
{
static_assert(tuple_holds<A, int>());
static_assert(tuple_holds<A, float>());
}
Run Code Online (Sandbox Code Playgroud)
我怀疑答案在于 SFINAE,但我不确定如何更进一步。
你不需要花哨的 C++20 特性来做到这一点。
template <typename, typename>
struct tuple_holds {};
template <typename ...A, typename B>
struct tuple_holds<std::tuple<A...>, B>
: std::bool_constant<(std::is_same_v<A, B> || ...)>
{};
Run Code Online (Sandbox Code Playgroud)
用法:tuple_holds<std::tuple<A, B>, C>::value。