How to make the compiler aware of templated struct? [duplicate] - c++

This question already has answers here:
Undefined reference to static variable c++
(3 answers)
Closed 6 years ago.
I am trying to implement an answer given on my question over at CodeReview.SE. Basically, I want to access some static variables in a templated struct. Consider the following example code:
#include <iostream>
using namespace std;
template<const int idx>
struct Data{
static int bar;
};
template<const int idx>
int getBar(){
return Data<idx>::bar;
}
int main() {
const int n = 2; // Arbitrary number
cout << getBar<n>();
return 0;
}
The compiler does not recognize that I want Data<n> to be available in the program - however, it recognizes the initial getBar<n> function just fine as is evident from the error message:
undefined reference to `Data<2>::bar'
How do I tell the compiler to make the templated struct available as well?

Static class variables must be given memory allocation. Add this:
template<const int idx>
int Data<idx>::bar = 0;
Demo
Edit: The dupe linked by NathanOliver hits it on the head, but for non-templated classes. This answer shows the syntax when the class is templated. minor difference, but still useful.

Related

Different ways of declaring a function in C++ [duplicate]

This question already has answers here:
How does this template magic determine array parameter size?
(3 answers)
Can someone explain this template code that gives me the size of an array? [duplicate]
(4 answers)
How does this "size of array" template function work? [duplicate]
(1 answer)
Closed 2 years ago.
I have come across the following code snippet in C++ and I have no idea what it means;
#include <iostream>
char (&some_function(int (&some_input)));
int main ()
{
// main code here
return 0;
}
How is some_function a function? what kind of syntax is this? where is the body?
I'm sure this is only a C++ syntax as it doesn't compile in C.
Edit:
Actual code with above style:
template <typename T, size_t N>
char (&ArraySizeHelper(T (&array)[N]))[N];
#define arraysize(array) (sizeof(ArraySizeHelper(array)))

Why is there a size_t defined in the global scope as well as in namespace std? [duplicate]

This question already has answers here:
Does "std::size_t" make sense in C++?
(8 answers)
Closed 5 years ago.
I've noticed that my C++ programs compile fine whether I use ::size_t or std::size_t. I can use them interchangeably with no issues at all, so it seems like one of them is a typedef for the other.
As an example, consider the following code which uses the global size_t (this is the whole file, no usings and other stuff):
#include <iostream>
int main() {
::size_t x = 100;
std::cout << x << std::endl;
}
The next code uses the size_t in std:
#include <iostream>
int main() {
std::size_t x = 100;
std::cout << x << std::endl;
}
Both compile fine and outputs 100 as expected.
I was under the impression that everything in the standard library is put in namespace std, but clearly this isn't the case. Why is this so?
Note: the same goes for ptrdiff_t, intN_t and uintN_t too.
According to what I've understood,::size_t and std::size_t are slightly different, but essentially the same, with a similar function.
There's a much better answer here: link
Hopes this helps!

C++ why my template expansion lead to compiler stack overflow? [duplicate]

This question already has answers here:
C++11 constexpr function compiler error with ternary conditional operator (?:)
(2 answers)
Closed 6 years ago.
I was trying template meta programming and writing a function to calculate power of base^re like 3^2=9
template<int N>
int Tpow(int base){return N==0?1:base*Tpow<N-1>(base);}
int main()
{
int r3=Tpow<3>(2);
return 0;
}
Just several lines, but it crashes both gcc and clang. Where did I get wrong?
Thanks.
Solution: You have to specialize your template for N equal 0. Like:
template<>
int Tpow<0>(int base){return 1;}
Now that you have this, you could also optimize your original template like so:
template<int N>
int Tpow(int base){return base*Tpow<N-1>(base);}
because you know you handle the case of N equal 0.
Explanation: Your compiler is basically doing this: It sees
int r3=Tpow<3>(2);
and makes a function for 3 as the template variable, like so
int Tpow_3(int base){return 3==0?1:base*Tpow<3-1>(base);}
and then it needs to make a function for 2 as template variable, like so
int Tpow_2(int base){return 2==0?1:base*Tpow<2-1>(base);}
and this goes on and on an on, because the compiler doesn't care about your 0==0?... yet.
The compiler must compile the entire function body: it cannot rely on the ternary conditional to only compile one side. So there is no block on the recursion.
(Using the constexpr of C++11 will not help either).
To solve this, you need to specialise the function for the N = 0 case.

zero an array inside a struct in c++ [duplicate]

This question already has answers here:
How come an array's address is equal to its value in C?
(6 answers)
Closed 7 years ago.
I have a struct defined in my program.
struct A{
int arr[10];
}
Lets say I have a pointer to it.
A * a = new A;
I can zero it in two ways:
memset(&a->arr,0,sizeof(A));
memset(a->arr,0,sizeof(A));
both work and look the same!
which one is more correct?
which one is more correct?
I'd argue neither. The easiest way would be to value initialize the allocated object:
A * a = new A();
Of course, this assumes that you actually have a good reason to new this object.
Since you are using C++ I would take advantage of C++11 features and use:
#include <iostream>
#include <cmath>
using namespace std;
struct A{
int arr[10]{}; // initializes array with all 0's
};
int main() {
A * a = new A;
for (auto e : a->arr) // ranged based for loop to show all of the 0's
cout << e << "\n";
return 0;
}
You can see it running with this Live Example
While the type of each expression is different, the actual result, the pointer you pass to memset, will be equal in both cases.
Personally I would probably use std::fill instead of memset in a C++ program:
std::fill(std::begin(a->arr), std::end(a->arr), 0);
Also note that if you have more members in the structure, sizeof(A) will be different from sizeof(a->arr) (or sizeof(A::arr)).
you can define a default construct function
struct A{
int arr[10];
A():arr(){}
};
This is the correct way for just the array
memset(a->arr,0,sizeof(a->arr))
Picked out the arr member just in case there are other structure members that do not need to be touched. Makes no difference in your example the following will do likewise
memset(a->arr,0,sizeof(A));

Why in C++ sizeof(array[]) behave in different way for bool array? [duplicate]

This question already has answers here:
When a function has a specific-size array parameter, why is it replaced with a pointer?
(3 answers)
Closed 9 years ago.
Why in C++ sizeof(array) behave in different way for bool array then for arrays containing other types of data ?
Edition :
I'm asking because
sizeof(boolarray)/sizeof(boolarray[0])
don't give size of boolarray.
but this simple code prints :
4
1
////////////////////////////
#include<iostream>
using namespace std;
void printBoolArray(bool* boolarray){
cout<<sizeof(boolarray)<<"\n";
cout<<sizeof(boolarray[0]);
}
int main(){
bool boolarray[10]={false};
printBoolArray(boolarray);
}
know I understand sizeof in function which gives the size of object which makes reference, this is my 9 day with c++, sorry for stupid question, it's so obvious now
It doesn't act differently. What makes you think it does? Are you making incorrect assumptions about the size of a bool?
As has been alluded to in the comments, if you are passing an array to a function and attempting to calculate its size there, that doesn't work. You can't pass arrays to (or return them from) functions. For example:
void foo(int array[10])
{
auto size = sizeof(array);
// size == sizeof(int*), you didn't pass an array
}
#include <cstddef>
#include <iostream>
template<std::size_t n>
void printBoolArray(bool (&boolarray)[n]){
std::cout<<sizeof(boolarray)<<"\n";
std::cout<<sizeof(boolarray[0]);
}
int main(){
bool boolarray[10]={false};
printBoolArray(boolarray);
}
The above works.
sizeof(bool*) is the size of the pointer, not the array it points to.
Above, I carefully maintained the type of the boolarray. As it happens, this technique also extracts the size into the compile-time constant n.
This doesn't scale well, because when you pass arrays to functions, they rapidly decay to pointers. This is one of the reasons why std::array or std::vector can be advised -- they have fewer quirks than C style arrays.
As others have explained, arrays degenerate to pointers when passed to a function.
However, there is one work around; you can use templates.
template<typename T, size_t N>
size_t length(T (&)[N]) {
return N;
}