我不完全确定你在问什么。我认为你提供的样本很有趣,并用它玩了一点。
我想出了一个实现,它span<a,b>
可以成为 的模板别名,indexes<a, ..., b>
使用constexpr
函数中的类型推导技巧:
template <int a, int b> using span = decltype(expand_span<a,b>());
现在你可以吃蛋糕了:
////////////////////////////////////////////////////////////////
// using indirect template arguments
template<typename> struct indirect_work { };
void test_indirect()
{
indirect_work<indexes<1,2,3,4>> x;
indirect_work<span<1,4>> y;
x = y; // x and y are of identical types
static_assert(std::is_same<indexes<1,2,3,4>, span<1,4>>::value, "fact check");
}
但是,也许更有趣的是,您仍然可以让您的主work
模板采用原始<int...>
模板参数列表:
////////////////////////////////////////////////////////////////
// using direct template arguments
template<int...> struct direct_work { };
// deduction alias:
template<int... direct> constexpr direct_work<direct...> deduction_helper(indexes<direct...>);
template <typename Idx> using deduce = decltype(deduction_helper(Idx{}));
void test_direct()
{
direct_work<1,2,3,4> x;
deduce<indexes<1,2,3,4>> y;
deduce<span<1,4>> z;
static_assert(std::is_same<decltype(x), decltype(y)>::value, "fact check");
static_assert(std::is_same<decltype(x), decltype(z)>::value, "fact check");
}
在此处查看完整的工作演示:gcc on ideone。我在本地用clang编译它。
完整代码
此处重复的代码expand_span
以防链接失效:
#include <type_traits>
template <int...> struct indexes {};
namespace {
template<int a, int... other>
constexpr indexes<a, other...> combine(indexes<other...> deduce);
template<int a, int b, typename Enable = void> struct expand_span_; // primary
template<int a, int b>
struct expand_span_<a, b, typename std::enable_if< (a==b), void >::type> {
static constexpr indexes<a> dispatch();
};
template<int a, int b>
struct expand_span_<a, b, typename std::enable_if< (a<b), void >::type> {
static constexpr decltype(combine<a>(expand_span_<a+1, b>::dispatch()))
dispatch();
};
template<int a, int b>
constexpr auto expand_span() -> decltype(expand_span_<a,b>::dispatch());
}
template <int a, int b> using span = decltype(expand_span<a,b>());
////////////////////////////////////////////////////////////////
// using indirect template arguments
template<typename> struct indirect_work { };
void test_indirect()
{
indirect_work<indexes<1,2,3,4>> x;
indirect_work<span<1,4>> y;
x = y; // x and y are of identical types
static_assert(std::is_same<indexes<1,2,3,4>, span<1,4>>::value, "fact check");
}
////////////////////////////////////////////////////////////////
// using direct template arguments
template<int...> struct direct_work { };
// deduction alias:
template<int... direct> constexpr direct_work<direct...> deduction_helper(indexes<direct...>);
template <typename Idx> using deduce = decltype(deduction_helper(Idx{}));
void test_direct()
{
direct_work<1,2,3,4> x;
deduce<indexes<1,2,3,4>> y;
deduce<span<1,4>> z;
static_assert(std::is_same<decltype(x), decltype(y)>::value, "fact check");
static_assert(std::is_same<decltype(x), decltype(z)>::value, "fact check");
}
int main()
{
test_indirect();
test_direct();
}