pmr*_*pmr 7 c++ template-meta-programming variadic-templates c++11
在最近关于boost开发者邮件列表的邮件中,Eric Niebler提到可以在O(1)实例化中获取模板参数包的最后一个元素.
如何才能做到这一点?
您可以查看https://github.com/ericniebler/proto-0x/blob/master/boost/proto/utility.hpp,如帖子中所述,关于get_nth元功能的实现方式.经过简单化后的本质:
#include <type_traits>
#include <cstdlib>
// A template to store a variadic list.
template <typename...>
struct List;
// Concatenate two variadic lists together. Should be O(1).
template <typename Left, typename Right>
struct Concat;
template <typename... Lefts, typename... Rights>
struct Concat<List<Lefts...>, List<Rights...>> {
typedef List<Lefts..., Rights...> Type;
};
// Construct List<void, void, void, ...> with 'n' elements.
// Uses "bisection" method, which should instantiate O(log n) templates
template <size_t n>
struct RepeatVoid : Concat<typename RepeatVoid<n/2>::Type,
typename RepeatVoid<n - n/2>::Type> {};
template <>
struct RepeatVoid<0> {
typedef List<> Type;
};
template <>
struct RepeatVoid<1> {
typedef List<void> Type;
};
Run Code Online (Sandbox Code Playgroud)
template <typename>
struct GetNthAux;
// This would create a function of the form:
//
// T eval(cv void*, cv void*, cv void*, ..., cv void*, T*, ...)
//
// where there are 'n' const volatile void*. These will be used to absorb
// the first 'n' template arguments. The actual one can be extracted from
// the return type.
//
template <typename... Ts>
struct GetNthAux<List<Ts...>> {
template<typename T>
static constexpr T eval(const volatile Ts*..., T*, ...);
};
// Run the whole thing.
template<size_t n, typename... Ts>
using GetNth = decltype(
GetNthAux<typename RepeatVoid<n>::Type>::eval((Ts*)nullptr...)
);
// Example:
int main() {
static_assert(std::is_same<GetNth<0, int, float, char>, int>::value, "");
static_assert(std::is_same<GetNth<1, int, float, char>, float>::value, "");
static_assert(std::is_same<GetNth<2, int, float, char>, char>::value, "");
}
Run Code Online (Sandbox Code Playgroud)
实际上它是O(log N),而不是O(1),因为它所用的时间RepeatVoid.
但是这种方法确实比线性方法表现得更好,比如典型的实现tuple_element<>.我试图比较的性能GetNth与tuple_element<>上得到一个列表的项目899,而后者是幅度较快的顺序:
tuple_element<> GetNth<>
g++ 4.7 with libstdc++ 0.7s 0.1s
clang++ 3.1 with libc++ 0.9s 0.1s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1015 次 |
| 最近记录: |