0

I have a school assignment where I have to code a template class that would store the minimum of a list of ints. When running it, I get parse errors but I don't understand why. Could someone explain why I'm getting these errors?

ListMin.hpp

template <int ... list>
class ListMin;

template <int first, int ... others>
class ListMin <first, others ...> {
public:
    enum : long { value = std::min(first, ListMin<others>::value) };
};

template <int first>
class ListMin <first> {
public:
    enum : long { value = first };
};

Main.cpp

std::cout << "min( [ 1, -5, 3 ] ) = " << ListMin< 1, -5, 3 >::value << std::endl;

The errors

ListMin.hpp:4: parse error before `...'
ListMin.hpp:7: parse error before `...'
ListMin.hpp:14: parse error before `<'

Thanks in advance

  • 1
    You need to enable c++11. Related: [https://en.cppreference.com/w/cpp/language/parameter_pack](https://en.cppreference.com/w/cpp/language/parameter_pack) – drescherjm Nov 15 '21 at 21:12
  • Any particular reason to use `enum` in this unusual manner, instead of a straightforward `constexpr int`? – Sam Varshavchik Nov 15 '21 at 21:13
  • Even in C++17 this doesn't build quite right, but I'll leave that to folks better at parameter packs to explain. – user4581301 Nov 15 '21 at 21:14
  • Out of general interest, what compiler and version are you using? I can't find one that reproduces your exact error message. – user4581301 Nov 15 '21 at 21:16
  • @user4581301 don't know the specific but as my professor just told us in an email: it's as old as me. Seems like not all computer classes on campus have up to date compilers. – DarkKooky Nov 15 '21 at 21:39
  • @SamVarshavchik i'm going off what my professor gave us an example as it's only my second month with C++. – DarkKooky Nov 15 '21 at 21:41
  • In a way, you're lucky. I can think of an entire subcontinent that up until recently primarily taught with a development environment that dates back to 1990. My recommendation: Give the teacher what they want and pass the class, but also squeeze in some time learning modern C++ so you have a smoother transition into the workforce. – user4581301 Nov 15 '21 at 21:42
  • Also note that a lot of the stuff you're going to find on the Internet is going to be completely useless to you and you're going to have to figure out which is which the hard way. cppreference.com clearly marks what's supported by what C++ Standards and the standard you're probably building to will be C++98. Any development you do on your own PC will have to be compiled to C++98 as well. This is usually set with a command line option like `-std=c++98`, or an option somewhere in a properties page in whatever GUI fronts the compiler. – user4581301 Nov 15 '21 at 21:50

1 Answers1

1

First problem: you need to expand the others pack.

Clang tells it up front:

<source>:9:27: error: enumerator value contains unexpanded parameter pack 'others'
    enum : long { value = std::min(first, ListMin<others>::value) };
                          ^                       ~~~~~~

Solution:

enum : long { value = std::min(first, ListMin<others...>::value) };
//                                                  ^~~

Second problem: std::min requires the arguments to have the same type. (Currently have int vs an unnamed enum).

enum : long { value = std::min(first, int(ListMin<others...>::value)) };
//                                    ^~~~                         ^

A much better solution would be to use std::min({1, 2, 3}), which is constexpr since C++14 (just like std::min(1, 2), which you already use).

Or at least, drop the archaic C-style unnamed enum and replace it with static constexpr int value = ...;.

HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207