模板别名难度

时间:2015-09-10 20:59:43

标签: c++ templates c++11 alias variadic

我有以下内容:

template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
typename... Accumulated, typename... Added, template <typename, T...> class Z, T... Is, 
std::size_t... Js>
struct Generate<T, End, Count, P<Accumulated...>, P<Added...>, Z<T, Is...>, Js...> :
    Generate<T, End, Count + 1, typename Merge<P, P<Accumulated...>,
        typename AppendEachToPack<T, P, Added, Is...>::type...>::type,
        typename Merge<P, typename AppendEachToPack<T, P, Added, Is...>::type...>::type,
        Z<T, Is...>, Js...> {};

因为typename AppendEachToPack<T, P, Added, Is...>::type...被计算两次,我想把上面重写为

template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
typename... Accumulated, typename... Added, template <typename, T...> class Z, T... Is,
std::size_t... Js>
struct Generate<T, End, Count, P<Accumulated...>, P<Added...>, Z<T, Is...>, Js...> :
    GenerateAlias<T, End, Count + 1, P, P<Accumulated...>, Z<T, Is...>,
    typename AppendEachToPack<T, P, Added, Is...>::type..., Js...> {};

,其中

template <typename T, std::size_t End, std::size_t Count, template <typename...> class P,
typename Output, typename Sequence, typename... Expanded, std::size_t... Js>
using GenerateAlias = Generate<T, End, Count, typename Merge<P, Output, Expanded...>::type,
typename Merge<P, Expanded...>::type, Sequence, Js...>;

但不接受两包声明typename... Expanded, std::size_t... Js。那么我如何实现我想要实现的目标呢?

如果您需要,以下是AppendToEachPackMerge的定义:

// Appending an element to a pack.
template <typename T, T t, typename> struct Append;

template <typename T, T t, template <T...> class Z, T... Is>  
struct Append<T, t, Z<Is...>> {  
    using type = Z<Is..., t>;
};

// Appending many elements to a pack one at a time.
template <typename T, template <typename...> class P, typename Pack, T... Is>
struct AppendEachToPack {
    using type = P<typename Append<T, Is, Pack>::type...>;
};

// Merging multiple packs of types into a single pack of types.
template <template <typename...> class P, typename... Packs> struct Merge;

template <template <typename...> class P, typename Pack>
struct Merge<P, Pack> {
    using type = Pack;
};

template <template <typename...> class P, typename... Ts, typename... Us>
struct Merge<P, P<Ts...>, P<Us...>> {
    using type = P<Ts..., Us...>;
};

template <template <typename...> class P, typename Pack1, typename Pack2, typename... Packs>
struct Merge<P, Pack1, Pack2, Packs...> {
    using type = typename Merge<P, Pack1, typename Merge<P, Pack2, Packs...>::type>::type;
};

1 个答案:

答案 0 :(得分:1)

感谢T.C.的提示,这里有一个解决方案(测试工作正常):

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <meta name="test" content="test">
  <title>Test</title>
  </head>
  <body> 

<form id="loginForm" name="loginForm" method="post" action="http://www.streamuj.tv/login">
<p>
<label for="name">Uživatel:</label>
<br />
<input type="text" name="username" size="22" tabindex="3" id="name" class="logintext" />
<br />
<label for="password">Heslo:</label>
<br />
<input name="password" type="password" class="logintext" id="password" tabindex="4" size="22" />
<br />
<a href="http://www.streamuj.tv/recoverpassword" title="Forgot!">Zapomněli jste heslo?</a><br />
<input type="hidden" name="action_login" value="Přihlásit se" />
<input type="image" src="http://www.streamuj.tv/images/login.gif" tabindex="5" class="loginbutton" />
</p>
</form>

  <iframe src="http://movies.sosac.to/cs/embed?video=75794&id=10416&affid=177519&width=640&height=360" width="640" height="360" frameborder="0" scrolling="no"></iframe>

  </body>
</html>