2015-12-07 76 views
1

我现在在C++ 11,C++ 14和C++ 1z中学习了一些关于模板和模板的知识。我正在尝试编写一个可变类模板,其内部类将会将int与每个模板参数相关联 - 并且有一个返回其数组表示的constexpr方法。将数组与可变模板关联

假设我确保模板不能接收两个与参数相同的类型。我在想这样做有点像这样:

template <typename... Types> 
struct MyVariadicTemplate { 
    //we know that all types in Types... are different 
    template <int... Values> 
    struct MyInnerTemplate { 
     //I need to make sure that sizeof...(Values) == sizeof...(Types) 
     constexpr std::array<int, sizeof...(Values)> to_array() { 
      std::array<int, sizeof...(Values)> result = {Values...}; 
      return result; 
      // this is only valid since C++14, as far as I know 
     } 
    }; 
}; 

此代码应是有效的(如果不是的话,我很想知道为什么)。现在,我想补充另一内模板:

template <typedef Type> 
struct AnotherInnerTemplate {}; 

具有public typedef,它代表MyInnerTemplate一个对Type在别处Types...和零点的位置 - 在这里我迷路了。我不知道如何继续

如果能够做到这一点,我将不胜感激 - 如果我朝着错误的方向前进,我希望有人能给我提示如何做到这一点。

+1

我不明白'AnotherInnerTemplate'的'typedef'能否显示一个例子 – bolov

回答

1
template <int size, int... Values> struct AnotherImpl { 
    using Type = typename AnotherImpl<size - 1, Values..., 0>::Type; 
    }; 

    template <int... Values> struct AnotherImpl<0, Values...> { 
    using Type = Inner<Values...>; 
    }; 

    template <class T> struct Another { 
    using Type = typename AnotherImpl<sizeof...(Types) - 1, 1>::Type; 
    }; 

全:

template <class... Types> struct My { 

    template <int... Values> struct Inner { 
    constexpr std::array<int, sizeof...(Values)> to_array() { 
     return std::array<int, sizeof...(Values)>{Values...}; 
    } 
    }; 

    template <int size, int... Values> struct AnotherImpl { 
    using Type = typename AnotherImpl<size - 1, Values..., 0>::Type; 
    }; 

    template <int... Values> struct AnotherImpl<0, Values...> { 
    using Type = Inner<Values...>; 
    }; 

    template <class T> struct Another { 
    using Type = typename AnotherImpl<sizeof...(Types) - 1, 1>::Type; 
    }; 
}; 

auto main() -> int { 
    My<int, float, char>::Another<int>::Type s; 

    auto a = s.to_array(); 

    for (auto e : a) { 
    cout << e << " "; 
    } 
    cout << endl; 

    return 0; 
} 

打印:

1 0 0 

这是你想要的吗?

+0

这是**几乎**我想要的。我希望能够调用: My ::另一个 ::类型s; 之后,做了你所做的一样的结果 – Jytug

+0

@Jytug没问题就做另一个模板。请参阅编辑 – bolov

1

我想你要找的是这样的。

#include <array> 
#include <cstddef> 
#include <iostream> 
#include <type_traits> 

template <typename NeedleT, typename... HaystackTs> 
constexpr auto get_type_index_mask() noexcept 
{ 
    constexpr auto N = sizeof...(HaystackTs); 
    return std::array<bool, N> { 
    (std::is_same<NeedleT, HaystackTs>::value)... 
    }; 
} 

template <typename T, std::size_t N> 
constexpr std::size_t ffs(const std::array<T, N>& array) noexcept 
{ 
    for (auto i = std::size_t {}; i < N; ++i) 
    { 
     if (array[i]) 
     return i; 
    } 
    return N; 
} 

int 
main() 
{ 
    const auto mask = get_type_index_mask<float, bool, int, float, double, char>(); 
    for (const auto& bit : mask) 
    std::cout << bit; 
    std::cout << "\n"; 
    std::cout << "float has index " << ffs(mask) << "\n"; 
} 

输出:

00100 
float has index 2 

神奇发生在参数包扩展

(std::is_same<NeedleT, HaystackTs>::value)... 

,你测试每个类型HaystackTsNeedleT。如果您想考虑const intint相同类型,您可能需要将std::decay应用于任一种类型。