我正在尝试在参数包中找到类型A
:
template <int I, typename A, typename B, typename ...C>
struct index_of
{
static constexpr int const value =
std::is_same<A, B>::value ? I : index_of<I + 1, A, C...>::value;
};
template <int I, typename A, typename B>
struct index_of<I, A, B>
{
static constexpr int const value =
std::is_same<A, B>::value ? I : -1;
};
这似乎有效,但是我无法消除非类型参数I
,我希望它是一个默认参数,但由于最后的参数包而不能这样做。如何消除/隐藏I
,以便元函数变得更加用户友好?
答案 0 :(得分:6)
您可以在命名空间中隐藏此实现,并使用另一个使用默认参数示例调用您的实现的类:
namespace detail
{
// your code as it is in the question
}
template <typename A, typename... B>
struct index_of
{
static int const value = detail::index_of<0, A, B...>::value;
};
修改强>
在他的评论中,DyP建议使用别名
来更简单地默认I
template <typename A, typename... B>
using index_of = detail::index_of<0, A, B...>;
答案 1 :(得分:3)
template <typename A, typename B, typename... C>
struct index_of
{
static constexpr int const value =
std::is_same<A, B>{}
? 0
: (index_of<A, C...>::value >= 0) ? 1+index_of<A, C...>::value : -1;
};
template <typename A, typename B>
struct index_of<A, B>
{
static constexpr int const value = std::is_same<A, B>{} -1;
};
请注意,std::is_same<A, B>{} -1
使用从bool
到int
的转换。
最好来自integral_constant
:
template <typename A, typename B, typename... C>
struct index_of
: std::integral_constant
< int,
std::is_same<A, B>{}
? 0
: (index_of<A, C...>{} == -1 ? -1 : 1+index_of<A, C...>{})
>
{};
template <typename A, typename B>
struct index_of<A, B>
: std::integral_constant < int, std::is_same<A, B>{} -1 >
{};
如果找不到类型,则无需返回-1
:
(如果有人知道如何在这里加入static_assert
以获得漂亮的诊断信息,我会很感激评论/编辑)
template <typename A, typename B, typename... C>
struct index_of
: std::integral_constant < std::size_t,
std::is_same<A, B>{} ? 0 : 1+index_of<A, C...>{} >
{};
template <typename A, typename B>
struct index_of<A, B>
: std::integral_constant<std::size_t, 0>
{
constexpr operator std::size_t() const
{
return std::is_same<A, B>{}
? 0
: throw std::invalid_argument("Type not found!");
}
};
答案 2 :(得分:1)
我的解决方案不使用std::is_same
template<typename Search, typename Head, typename... Tail>
struct index {
static constexpr size_t value =
1 + index<Search, Tail...>::value;
};
template<typename Search, typename... C>
struct index<Search, Search, C...> {
static constexpr size_t value = 0;
};