为什么这段代码抱怨“非类型模板参数不能有类型”?

时间:2018-05-08 10:20:39

标签: c++ templates c++14 variadic-templates

代码:

#include <functional>
#include <type_traits>

namespace impl
{
    // lame recursive implementation
    template<typename Functor, Functor F, typename T, T OneValue, T SecondValue, T... Values>
    struct variadic_conjunction : variadic_conjunction<Functor, F, T, F(OneValue, SecondValue), Values...> {};

    template<typename Functor, Functor F, typename T, T OneValue, T SecondValue>
    struct variadic_conjunction<Functor, F, T, OneValue, SecondValue> : std::integral_constant<T, F(OneValue, SecondValue)> {};
}

template<typename Functor, Functor F, typename T, T... Values>
struct variadic_conjunction : impl::variadic_conjunction<Functor, F, T, Values...> {};

template<typename Functor, Functor F, typename T, T... Values>
constexpr T variadic_conjunction_v = variadic_conjunction<Functor, F, T, Values...>::value;

template<typename T, T... Values>
struct variadic_max : variadic_conjunction<std::greater<T>, std::greater<T>{}, T, Values...> {};

template<typename T, T... Values>
constexpr T variadic_max_v = variadic_max<T, Values...>::value;

int main()
{
    constexpr auto max = variadic_max_v<std::size_t, 4, 8>;
}

你可以在coliru上玩它:http://coliru.stacked-crooked.com/a/17c5065229594de9

抱怨这个:

main.cpp:14:36: error: a non-type template parameter cannot have type 'std::__1::greater<unsigned long>'
template<typename Functor, Functor F, typename T, T... Values>
                                   ^
main.cpp:21:23: note: while substituting prior template arguments into non-type template parameter 'F' [with Functor = std::__1::greater<unsigned long>]
struct variadic_max : variadic_conjunction<std::greater<T>, std::greater<T>{}, T, Values...> {};
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:24:30: note: in instantiation of template class 'variadic_max<unsigned long, 4, 8>' requested here
constexpr T variadic_max_v = variadic_max<T, Values...>::value;
                             ^
main.cpp:28:26: note: in instantiation of variable template specialization 'variadic_max_v<unsigned long, 4, 8>' requested here
    constexpr auto max = variadic_max_v<std::size_t, 4, 8>;
                         ^
main.cpp:28:26: error: constexpr variable 'max' must be initialized by a constant expression
    constexpr auto max = variadic_max_v<std::size_t, 4, 8>;
                         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

2 errors generated.

但据我所知,我正在传递std::greater<T>的实例(注意大括号初始化{})。

我也不确定第二个错误,但我会稍后再说。

2 个答案:

答案 0 :(得分:3)

您正在尝试使用<?php $nav = cr_get_menu_items('navigation_menu') ?> <!-- Display parent items. --> <?php $nav = cr_get_menu_items('navigation_menu') ?> <?php foreach ($nav as $link): if ($link->menu_item_parent == 0) : ?> <a class="main-nav" href="<?= $link->url ?>"><?= $link->title ?></a> <?php endif; endforeach; ?> <!-- Display children items. (in its own wrapper `div`/`ul`/etc.) --> <?php $_ids = []; ?> <?php foreach ($nav as $link): $parent = (int) $link->menu_item_parent; if ( 0 !== $parent && ! in_array( $parent, $_ids ) ) : ?> <!-- This `div` is just an example wrapper. --> <div class="menu-<?= $parent ?>-subnav"> <?php foreach ( cr_get_submenu_items( $nav, $parent ) as $clink ): ?> <a href="<?= $clink->url ?>"><?= $clink->title ?></a> <?php endforeach; ?> <?php $_ids[] = $link->menu_item_parent; ?> </div> <?php endif; endforeach; ?> 参数化模板,这不是模板参数(cppreference)的可接受类型:

  • std::greater<T>(自C ++ 11起)
  • 整数类型(注意:std::nullptr_t是整数类型)
  • 左值引用类型(对象或函数);
  • 指针类型(对象或函数);
  • 指向成员类型的指针(指向成员对象或成员函数);
  • 枚举类型。

答案 1 :(得分:0)

https://en.cppreference.com/w/cpp/container/priority_queue,它使用

template<
    class T,
    class Container = std::vector<T>,
    class Compare = std::less<typename Container::value_type>
> class priority_queue;

我们可以看到 Compare 使用 typename/class,而不是 std::function<...> 这是因为 std::greater 是一个结构体:

template< class T = void >
struct greater;