12

I have:

#include <cstdlib>
#include <vector>

using namespace std;

int main()
{
   auto a = -SOME_CONST_MAX;
   vector<auto> myVec {a, a, a, a};
}

I don't know the type of the SOME_CONST_MAX but I want to make a vector of the type of -SOME_CONST_MAX. I assumed vector<auto> would work as it will deduce from type of a.

I'm getting these errors running: g++ -std=c++14 main.cpp

main.cpp:9:9: error: invalid use of ‘auto’
  vector<auto> myVec {a, a, a, a};
         ^
main.cpp:9:13: error: template argument 1 is invalid
  vector<auto> myVec {a, a, a, a};
             ^
main.cpp:9:13: error: template argument 2 is invalid
main.cpp:9:32: error: scalar object ‘myVec’ requires one element in initializer
  vector<auto> myVec {a, a, a, a};
                                ^

Is vector<auto> not allowed? What am I doing wrong?

soundslikeodd
  • 1,078
  • 3
  • 19
  • 32
Robert C. Holland
  • 1,651
  • 4
  • 24
  • 57
  • 17
    you can use `vector` instead – Slava Jan 24 '17 at 20:53
  • 10
    C++17 will introduce template type deduction for class templates, so you'll be allowed to do something like `vector myVec{a,a,a,a};` and the compiler will deduce the type of `myVec` as `vector`. – vsoftco Jan 24 '17 at 20:58
  • 1
    highly related: http://stackoverflow.com/questions/984394/why-not-infer-template-parameter-from-constructor – NathanOliver Jan 24 '17 at 20:58
  • @Slava - very simple and elegant: IMHO, you should propose it as an answer – max66 Jan 24 '17 at 21:05
  • @max66 the problem that it is not answer to the question "Is vector not allowed?" Which probably requires reference to the C++ standard. – Slava Jan 24 '17 at 21:11
  • 1
    To note, with the Concepts TS, `std::vector` is allowed [in some contexts](http://melpon.org/wandbox/permlink/waxJhbwnYICIqjxQ). – chris Jan 24 '17 at 21:20
  • @chris Oh boy, why does thing needs to become more and more complex? Concepts is a great idea, but allowing `std::vector v = ...` and class template type deduction like `std::vector v = ...` will definitely not make things simpler. – vsoftco Jan 25 '17 at 01:15

2 Answers2

11

I find Slava's solution really simple and elegant

vector<decltype(a)> myVec {a, a, a, a};

But just to show another way, you can use the variadic template function

template <typename T, typename ... Ts>
std::vector<T> getVect (T const & t, Ts const & ... ts)
 { return { t, ts... } ; }

You can use auto again

auto myVec = getVect(a, a, a, a, a);
max66
  • 65,235
  • 10
  • 71
  • 111
10

If I remember correctly, proposals have been made for vector<auto> syntax. They where not accepted by the C++ standard committee.

C++17 will introduce something like std::vector bob = {a,a,a,a}; that just works. Note the lack of <auto>. This may just be the language feature, with actual use in std following afterward.

auto is also added to templates, but auto is always a value never a type. So using auto to replace a type was considered a bad idea.

Here is a use of auto in a template:

template<auto x>
using constant_t=std::integral_constant<decltype(x),x>;
template<auto x>
constexpr constant_t<x> constant{};

and now constant<7> is a std::integral_constant<int,7>. This is considered useful for many reasons.

The answer to your practical problem using current C++ is:

auto a = -SOME_CONST_MAX;
std::vector<decltype(a)> myVec {a, a, a, a};

where we deduce the type of a and pass it to vector.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524