Small question

In this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <type_traits> 
#include <iostream> 
 
int main() 
    { 
    int *p = (std::remove_reference<int&>::type *)0; 
 
    p = p;  // to quiet "unused" warning 
    std::cout << "remove_reference<int&> == " 
        << typeid(*p).name() << std::endl; 
 
    return (0); 
    } 
 


Why do you need the :: before type * in

int *p = (std::remove_reference<int&>::type *)0;

Can someone please explain cause it works perfectly fine without it in this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Ex8_10.cpp
// Using a class template
#include <iostream>
#include <utility>                          // For operator overload templates
using std::cout;
using std::endl;
using std::move;
using namespace std::rel_ops;
        
class CBox                                  // Class definition at global scope
{
  public:
    // Constructor definition
    explicit CBox(double lv = 1.0, double wv = 1.0, double hv = 1.0): m_Height(hv)
    {
      m_Length = std::max(lv, wv);
      m_Width = std::min(lv, wv);

      // Length is now greater than or equal to width 
      if(m_Height > m_Length)
      {
        m_Height = m_Length;
        m_Length = hv;

        // m_Height is still greater than m_Width so swap them
        double temp = m_Width;
        m_Width = m_Height;
        m_Height = temp;
      }
      else if( m_Height > m_Width)
      {
        m_Height = m_Width;
        m_Width = hv;
      }
    }
        
    // Function to calculate the volume of a box
    double Volume() const
    {
      return m_Length*m_Width*m_Height;
    }
        
    // Operator function for 'less than' that
    // compares volumes of CBox objects.
    bool operator<(const CBox& aBox) const
    {
      return this->Volume() < aBox.Volume();
    }

    // 'Less than' operator function to compare a CBox object volume with a constant
    bool operator<(const double& value) const
    {
      return this->Volume() < value;
    }

    // 'Greater than' function to compare a CBox object volume with a constant
    bool operator>(const double& value) const
    {
      return this->Volume() > value;
    }
        
    // Overloaded equality operator
    bool CBox::operator==(const CBox& aBox) const
    {
      return this->Volume() == aBox.Volume();
    }

    // Function to add two CBox objects
    CBox operator+(const CBox& aBox) const
    {
      // New object has larger length & width, and sum of heights
      return CBox(m_Length > aBox.m_Length ? m_Length : aBox.m_Length,
                  m_Width > aBox.m_Width   ?  m_Width : aBox.m_Width,
                  m_Height + aBox.m_Height);
    }

    // Function to show the dimensions of a box
    void ShowBox() const
    {
      cout << m_Length << " " << m_Width  << " " << m_Height << endl;
    }
        
  private:
    double m_Length;                        // Length of a box in inches
    double m_Width;                         // Width of a box in inches
    double m_Height;                        // Height of a box in inches
};
        
// CSamples class template definition
template <class T> class CSamples
{
  public:
    // Constructors
    CSamples(const T values[], int count);
    CSamples(const T& value);
    CSamples(T&& value);
    CSamples() : m_Free(0) {}
        
    bool Add(const T& value);               // Insert a value
    bool Add(T&& value);                    // Insert a value with mve semantics
    T Max() const;                          // Calculate maximum
        
  private:
    static const size_t maxSamples = 100;   // Maximum number od sample
    T m_Values[maxSamples];                 // Array to store samples
    int m_Free;                             // Index of free location in m_Values
};

// Constructor template definition to accept an array of samples
template<class T> CSamples<T>::CSamples(const T values[], int count)
{
  m_Free = count < maxSamples ? count : maxSamples;       // Don't exceed the array
  for(int i = 0; i < m_Free; i++)
    m_Values[i] = values[i];                // Store count number of samples
}
        
// Constructor to accept a single sample
template<class T> CSamples<T>::CSamples(const T& value)
{
  m_Values[0] = value;                      // Store the sample
  m_Free = 1;                               // Next is free
}
        
// Constructor to accept a temporary sample
template<class T> CSamples<T>::CSamples(T&& value)
{
  cout << "Move constructor." << endl;
  m_Values[0] = move(value);                // Store the sample
  m_Free = 1;                               // Next is free
}
        
// Function to add a sample
template<class T> bool CSamples<T>::Add(const T& value)
{
  cout << "Add." << endl;
  bool OK = m_Free < maxSamples;                   // Indicates there is a free place
  if(OK)
    m_Values[m_Free++] = value;             // OK true, so store the value
  return OK;
}
        
template<class T> bool CSamples<T>::Add(T&& value)
{
  cout << "Add move." << endl;
  bool OK = m_Free < maxSamples;                   // Indicates there is a free place
  if(OK)
    m_Values[m_Free++] = move(value);       // OK true, so store the value
  return OK;
}
 
// Function to obtain maximum sample
template<class T> T CSamples<T>::Max() const
{
  T theMax = m_Values[0];                   // Set first sample as maximum
  for(int i = 1; i < m_Free; i++)           // Check all the samples
    if(theMax < m_Values[i])
      theMax = m_Values[i];                 // Store any larger sample
  return theMax;
}
        
int main()
{
  CBox boxes[] = {                          // Create an array of boxes
                   CBox(8.0, 5.0, 2.0),     // Initialize the boxes...
                   CBox(5.0, 4.0, 6.0),
                   CBox(4.0, 3.0, 3.0)
                 };
        
  // Create the CSamples object to hold CBox objects
  CSamples<CBox> myBoxes(boxes, _countof(boxes));
        
  CBox maxBox = myBoxes.Max();              // Get the biggest box
  cout << endl                              // and output its volume
       << "The biggest box has a volume of "
       << maxBox.Volume()
       << endl  << endl;

  CSamples<CBox> moreBoxes(CBox(8.0, 5.0, 2.0));
  moreBoxes.Add(CBox(5.0, 4.0, 6.0));
  moreBoxes.Add(CBox(4.0, 3.0, 3.0));
  cout << "The biggest box has a volume of "
       << moreBoxes.Max().Volume()
       << endl;
  return 0;
}


It works without it on line 170 perfectly fine but without it in the first code it doesnt work? Can someone please explain!
The use of std::remove_reference on the original snippet seems rather arbitrary and has no effect on the output. What is the purpose of using it?

The subsequent code is not in any way related to the original snippet.

Please explain why you think that isn't true.
The resolution operator? What need is it in the remove_reference. I know that it is useless there but why does it need the :: before type * but in the second snippet my class doesn't need it?
You need a :: before type because that's the syntax uses to access a public member type. In this case, the class std::remove_reference<int&> has a public member typedef called std::remove_reference<int&>::type (which is exactly the same as just int, so, as cire said, it's pretty pointless -- you wrote "int* p = (int *)0;")
What exactly do you mean public member type?



classes can have four kinds of members: data members, member functions, member enumerators, and member types. "type" above is a type.
(and any member has public, protected, or private access)
Last edited on
So to access that you dont use the member access operator, the period (.)?

You use the scope resolution operator?
i am not an expert. i think that the problem is with your understanding about :: and . .
. is used to access member functions or member variables using an object. so we first need to create an object of a class and then we can use . to access public members of that class.

:: is used to access members of class without creating an object. we directly use classname :: member . all members cant be accessed using this scope resolution operator. enumerators, member types and static functions can be accessed without creating an object of a class, using :: .

sorry for my bad english.
Last edited on
Oh ok thanks :D
Topic archived. No new replies allowed.