0

I am learning C++ class templates. Below is my code. When I run it, I get the error "required from here". It would be great help if someone can point out the issue. The error line number corresponds to instantiation of frank object.

#include <iostream>
#include <string>

template <typename T>               
class Data
{
private:
                                       
    std::string name;
    T value; 
public:
    Data(std::string n, T v) : value {v}, name {n}
    {
        
    }
    ~Data() = default; 
    
    T getValue()
    {
        return value;
    }
    std::string getName()
    {
        return name;
    }
};

int main()
{
    Data<int> frank {"frank", 35};                                 
    
    std::cout << std::endl;
}

Error message

Adding Build log:

C:\WINDOWS\system32\cmd.exe /C mingw32-make.exe -j 8 -e -f  Makefile
"----------Building project:[ TestArea - Debug ]----------"
mingw32-make.exe[1]: Entering directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
mingw32-make.exe[1]: Leaving directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
mingw32-make.exe[1]: Entering directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
g++  -c  "C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp" -g -O0 -std=c++14 -Wall  -o ./Debug/main.cpp.o -I. -I.
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp: In instantiation of 'Data<T>::Data(std::__cxx11::string, T) [with T = int; std::__cxx11::string = std::__cxx11::basic_string<char>]':
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:30:33:   required from here
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:10:7: warning: 'Data<int>::value' will be initialized after [-Wreorder]
     T value;
       ^
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:9:17: warning:   'std::__cxx11::string Data<int>::name' [-Wreorder]
     std::string name;
                 ^
C:/Users/LPC/Documents/C_Plus_Plus/TestArea/main.cpp:12:5: warning:   when initialized here [-Wreorder]
     Data(std::string n, T v) : value {v}, name {n}
     ^
g++ -o ./Debug/TestArea @"TestArea.txt" -L.
mingw32-make.exe[1]: Leaving directory 'C:/Users/LPC/Documents/C_Plus_Plus/TestArea'
====1 errors, 3 warnings====
Evg
  • 25,259
  • 5
  • 41
  • 83
ligin pc
  • 31
  • 3
  • 2
    That's just a part from the warning message that spans several lines. The relevant part is "warning: `Data::value` will be initialized after `std::string Data::name`". – Evg Aug 14 '21 at 06:52
  • Please copy and paste the entire set of compiler messages as text. Images are not useful. – n. m. could be an AI Aug 14 '21 at 06:53
  • 3
    It appears to be saying the order your member variables are declared and the order of your constructor initialization list don't match. The variables will be initialized in the order declared, not the order of the list. It also looks like a warning, not an error. It would be easier to see as text. https://godbolt.org/z/MdrbcKGxT – Retired Ninja Aug 14 '21 at 06:53
  • Added log in the question – ligin pc Aug 14 '21 at 06:57
  • 1
    I don't see an actual error. Perhaps fix the warning and see what happens. I copy/pasted your code and it compiled fine. – Retired Ninja Aug 14 '21 at 07:00
  • When I do initialization of members in constructor in the same order as it is declared, there is no error. Is there any rule like that while using class templates? – ligin pc Aug 14 '21 at 07:02
  • It compiled for me tooo. May It is compiler specific error! –  Aug 14 '21 at 07:04
  • @Elliott Its g++ 5.1.0 – ligin pc Aug 14 '21 at 07:12
  • 1
    refer this documentation https://en.cppreference.com/w/cpp/language/aggregate_initialization –  Aug 14 '21 at 07:13

2 Answers2

2

It has nothing to do with templates.

The warning is here because programmers often assume (incorrectly) that

: value {v}, name {n}`

means that value is initialised before name. In fact the initialisation order matches the declaration order:

std::string name;
T value; 

Initialisation order doesn't matter in your case, but it does matter quite often. Thus it is in general a good habit to avoid surprises and make the order in which initialisers appear always match the declaration order. So just do that.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
  • Upvote for including the part about us programmers assuming things and about the fact that there are case were it does indeed matter a lot. – Bart Aug 14 '21 at 07:17
1

To resolve the warning, not an error, switch around the order of your initializer list in the constructor.

template <typename T>               
class Data
{
  private:                                     
    std::string name; // <--- Here you define name first.
    T value; 
  public:
    Data(const std::string& n, const T& v) : name {n}, value {v} // <---
                                             // This means here name will be 
                                             // initialized first as it first appears 
                                             // in the memory model of your class.
    {
        
    }
};
Bart
  • 1,405
  • 6
  • 32
  • Although you've implied it, it might be worth emphasising that this wasn't an error. =) – Elliott Aug 14 '21 at 07:12
  • Exactly it is a warning and the code will do it any way. – Bart Aug 14 '21 at 07:14
  • Not really related to the question, but consider passing std::string as const std::string& and T as const T&. This will help with performance and you will promise not to change the values of n and v in the body of the code – Pepijn Kramer Aug 14 '21 at 07:18
  • @pepijn indeed will add it in the example – Bart Aug 14 '21 at 07:20