Error: Invalid Initialization of Non-Const Reference of Type 'Int&' from an Rvalue of Type 'Int'

error: invalid initialization of non-const reference of type 'cv::Mat&'

You cannot bind a non-const reference to a temporary. In your case the first argument to devectorize is a non-const reference and the return value from V.col(i) is the temporary. This code would work

for (int i = 0; i < V.cols; i++)
{
Mat tmp = V.col(i);
devectorize(tmp, mask, E_img);
}

so would changing the first parameter of devectorize to const Mat&.

initial value of reference to non-const must be an lvalue

When you pass a pointer by a non-const reference, you are telling the compiler that you are going to modify that pointer's value. Your code does not do that, but the compiler thinks that it does, or plans to do it in the future.

To fix this error, either declare x constant

// This tells the compiler that you are not planning to modify the pointer
// passed by reference
void test(float * const &x){
*x = 1000;
}

or make a variable to which you assign a pointer to nKByte before calling test:

float nKByte = 100.0;
// If "test()" decides to modify `x`, the modification will be reflected in nKBytePtr
float *nKBytePtr = &nKByte;
test(nKBytePtr);

Perfect Forwarding in C++03

This is mentioned as a potential solution in the document I linked in the recent C++0x forwarding question.

It would work fairly well, but it breaks existing code. Consider (straight from the document):

template<class A1> void f(A1 & a1)
{
std::cout << 1 << std::endl;
}

void f(long const &)
{
std::cout << 2 << std::endl;
}

int main()
{
f(5); // prints 2 under the current rules, 1 after the change
int const n(5);
f(n); // 1 in both cases
}

Or

// helper function in a header

template<class T> void something(T & t) // #1
{
t.something();
}

// source

#include <vector>

void something(bool) // #2
{
}

int main()
{
std::vector<bool> v(5);

// resolves to #2 under the current rules, #1 after the change
something(v[0]);
}

This also fails to forward the value category (lvalue or rvalue), which isn't much of a problem in C++03. But since this fix could only be done during C++0x, we'd effectively shutting ourselves out from rvalue references when forwarding (a bad thing). We should strive for a better solution.

value-initialization of a const member reference

This code is ill-formed. You can't default initialize or value initialize a reference.

If you actually had an expression inside of ref(), then yes, 12.2.5 would apply and the temporary would be destroyed when the constructor exits.

Why do C and C++ support memberwise assignment of arrays within structs, but not generally?

Here's my take on it:

The Development of the C Language offers some insight in the evolution of the array type in C:

  • http://cm.bell-labs.com/cm/cs/who/dmr/chist.html

I'll try to outline the array thing:

C's forerunners B and BCPL had no distinct array type, a declaration like:

auto V[10] (B)
or
let V = vec 10 (BCPL)

would declare V to be a (untyped) pointer which is initialized to point to an unused region of 10 "words" of memory. B already used * for pointer dereferencing and had the [] short hand notation, *(V+i) meant V[i], just as in C/C++ today. However, V is not an array, it is still a pointer which has to point to some memory. This caused trouble when Dennis Ritchie tried to extend B with struct types. He wanted arrays to be part of the structs, like in C today:

struct {
int inumber;
char name[14];
};

But with the B,BCPL concept of arrays as pointers, this would have required the name field to contain a pointer which had to be initialized at runtime to a memory region of 14 bytes within the struct. The initialization/layout problem was eventually solved by giving arrays a special treatment: The compiler would track the location of arrays in structures, on the stack etc. without actually requiring the pointer to the data to materialize, except in expressions which involve the arrays. This treatment allowed almost all B code to still run and is the source of the "arrays convert to pointer if you look at them" rule. It is a compatiblity hack, which turned out to be very handy, because it allowed arrays of open size etc.

And here's my guess why array can't be assigned: Since arrays were pointers in B, you could simply write:

auto V[10];
V=V+5;

to rebase an "array". This was now meaningless, because the base of an array variable was not a lvalue anymore. So this assigment was disallowed, which helped to catch the few programs that did this rebasing on declared arrays. And then this notion stuck: As arrays were never designed to be first class citized of the C type system, they were mostly treated as special beasts which become pointer if you use them. And from a certain point of view (which ignores that C-arrays are a botched hack), disallowing array assignment still makes some sense: An open array or an array function parameter is treated as a pointer without size information. The compiler doesn't have the information to generate an array assignment for them and the pointer assignment was required for compatibility reasons. Introducing array assignment for the declared arrays would have introduced bugs though spurious assigments (is a=b a pointer assignment or an elementwise copy?) and other trouble (how do you pass an array by value?) without actually solving a problem - just make everything explicit with memcpy!

/* Example how array assignment void make things even weirder in C/C++, 
if we don't want to break existing code.
It's actually better to leave things as they are...
*/
typedef int vec[3];

void f(vec a, vec b)
{
vec x,y;
a=b; // pointer assignment
x=y; // NEW! element-wise assignment
a=x; // pointer assignment
x=a; // NEW! element-wise assignment
}

This didn't change when a revision of C in 1978 added struct assignment ( http://cm.bell-labs.com/cm/cs/who/dmr/cchanges.pdf ). Even though records were distinct types in C, it was not possible to assign them in early K&R C. You had to copy them member-wise with memcpy and you could pass only pointers to them as function parameters. Assigment (and parameter passing) was now simply defined as the memcpy of the struct's raw memory and since this couldn't break exsisting code it was readily adpoted. As a unintended side effect, this implicitly introduced some kind of array assignment, but this happended somewhere inside a structure, so this couldn't really introduce problems with the way arrays were used.

How you convert a std::string_view to a const char*?

A std::string_view doesn't provide a conversion to a const char* because it doesn't store a null-terminated string. It stores a pointer to the first element, and the length of the string, basically. That means that you cannot pass it to a function expecting a null-terminated string, like foo (how else are you going to get the size?) that expects a const char*, and so it was decided that it wasn't worth it.

If you know for sure that you have a null-terminated string in your view, you can use std::string_view::data.

If you're not you should reconsider whether using a std::string_view in the first place is a good idea, since if you want a guaranteed null-terminated string std::string is what you want. For a one-liner you can use std::string(object).data() (note: the return value points to a temporary std::string instance that will get destroyed after the end of the expression!).

error: no matching function for call to ‘std::__cxx11::basic_string char ::basic_string(int&)’

This statement

a = new T(MAX);

tries to create an object of the type std::string from the integer value MAX. However the class std::string has no such a constructor.

It seems you mean

a = new T[MAX];

that is you want to create an array of objects of the type std::string.

This function

T Stack<T>::peek() { 
if (top < 0) {
cout << "Stack is Empty" << endl;
return NULL;
} else {
return a[top];
}
}

is also wrong because creating an object of the type std::string from a null pointer results in undefined behavior. You should throw an exception for example std::out_of_range.

Pay attention to that the class has no destructor.

Instead of the dynamically allocated array you could use the class std::vector<std::string>.



Related Topics



Leave a reply



Submit