Error specifying non-type template parameter

81 views Asked by At

I have the following code:

//code.h

#ifndef CODE_H
#define CODE_H

#include<vector>
#include<numeric>
#include<cstddef>
#include<algorithm>
#include<iostream>

using std::vector;
using std::iota;
using std::size_t;
using std::for_each;
using std::cout;
using std::endl;

template<typename T, const size_t s, const T min>
class obj{
  public:
   obj();
   obj(const obj&)=delete;
   obj& operator=(const obj&)=delete;
   void print();

  protected:

  private:
  vector<T> v(s); 
};

template<typename T, const size_t s, const T min>
obj<T,s,min>::obj(){
 iota(v.begin(), v.end(), min); 
}

template<typename T, const size_t s, const T min>
obj<T,s,min>::print(){
 for_each(v.begin(), v.end(), [](const T& t){cout << t << " ";});
 cout << endl;
 return;
}

#endif

//main.cpp
#include "code.h"

int main (){
  obj<int,5,0> V;
  V.print();
  return 0;
}

I have the following alias setting for my compiler option:

alias g++compile='g++ -ggdb -g3 -pedantic-errors -Wall -Wextra -Wfatal-errors -Wpedantic -std=c++17'

Upon compilation, the above code gives me the following error:

In file included from main.c:1:
code.h:29:15: error: ā€˜s’ is not a type
   29 |   vector<T> v(s);
      |               ^
compilation terminated due to -Wfatal-errors.

My understanding is that since I have specified the type of the non-type template parameter in the template header, the compiler should be able to correlate s in the body of the template to its type size_t.

What am I missing here? Can someone tell me the correct way to refer to the non-type template parameter in the body of the template?

TIA

1

There are 1 answers

0
JeJo On BEST ANSWER

What am I missing here?

You are having the most vexing parse. The following is considered as a member function declaration, rather than a data member.

vector<T> v(s);
^^^^^^^^^     ---- > return type of the function
          ^   ---- > member function called "v".
           ^^ ---- > "s" is considered as an identifier, rather a type, hence the compiler error!

Can someone tell me the correct way to refer to the non-type template parameter in the body of the class template?

As mentioned above, this has nothing to do with s being a non-template argument, but a most vexing parse issue.

You can fix the default member initializer either by

template<typename T, const size_t s, const T min>
class obj 
{
    // ....
private:
    std::vector<T> v{ std::vector<T>(s) };
};

or by

template<typename T, const size_t s, const T min>
class obj 
{
    // ....
private:
    std::vector<T> v = std::vector<T>(s);
};

That being said, if the size s is fixed and known at compile time, for the obj class template, std::array<T, s> would have been a better data structure here, unless you want to store them dynamically allocated memory.