1

This is rather a quick question.

I have a function:

template<class T> T& read(T& value)
{
    // Read an value of type T and assign it to variable "value"
    return value;
}

Now I can use the function as:

char c;
read(c);

But I want to use this function as:

char c = read(char());

Is that possible, or do I have to use it as:

char c = read<char>();

? (I know in the latter I have to adjust the function a bit)

6
  • Why do you think you need references? Commented Oct 17, 2012 at 12:23
  • Not in this case, but let's say for huge classes. Commented Oct 17, 2012 at 12:27
  • I always envy ppl who are able to determine whether a question is quick, regardless of whether they solved it already. Commented Oct 17, 2012 at 12:35
  • @phresnel Well maybe I'm learning C++, and I was wondering if something was possible somehow, but couldn't find the answer anywhere, so I thought to ask it, and someone could give me a simple yes or no.. Commented Oct 17, 2012 at 12:38
  • @Tim: You have to decide whether you want to take an object as argument and update it (read into it) or else you want to create the object in the function. In your two last usage examples the function creates, while in the first one it takes and existing object. Decide how you want your interface to be and then work it up from there. Commented Oct 17, 2012 at 12:40

5 Answers 5

1

No it is not, because a temporary (your char()) cannot bind to a non-const reference. The reference can't be const due to your requirements ("Read an value of type T and assign it to variable "value"").

An alternative:

template<class T> T read()
{
    // Read an value of type T and assign it to variable "value"
    return T();
}

//...
c = read<char>();
Sign up to request clarification or add additional context in comments.

Comments

1

No, you can't, and probably don't want to either. You cannot bind a temporary to a non-const reference parameter. What's the use of returning value and assigning to the parameter anyway? This doesn't make sense.

Just use this:

template<class T> T read()
{
    // Read an value of type T and assign it to variable "value"
    return value;
}

EDIT: removed the & from the return value.

3 Comments

Probably don't want to be returning a reference here either, if your create it in the scope of this function
@LuchianGrigore: Whatever it is in the OP's code. (Have to replace the comment with something useful).
My question was to steer you into removing the reference from the return type :)
0

In your template you say that you want to the compiler that you have a function that get an editable reference to type T and return an editable reference to that type, so you can use it as : char c; read( c ); but you can't use it as read( char() ), since char() is not editable(l-value), since you can't use it in left side of equal operator: char() = 3 is invalid. If you don't want to change input you can have something like:

template< class T >
T read( const T& val ) {
    // do something with val and return a T
    return val;
}

then you can call it as :

read( char() );
read (char)1 );
char c = read( (char)2 );
read( c );

and if you want a default value then it is just as simple as previous example:

template< class T >
T read( const T& val = T() ) {
    // do something with val and return a T
    return val;
}

and then you are able to call char c = read<char>()

1 Comment

Thanks thats even better! Except the const though.
0

The first one you gave doesn't actually make sense. Think about it, you pass in an anonymous value, no variable is bound to it. How can you assign to it then? What would be changed?

Since char() is an rvalue, you can't use it as a non-const reference, that you can only do with an lvalue

In this case references all together aren't necessary. If you wanted to do what your explained in your question try:

template<typename T>
T readT(){
  T v;
  read(v);
  return v;
}

Now we can type this:

char c = readT<char>();

Which does what you want.

1 Comment

Because a char in this case has been read from a stream and passed to the reference.
0

All right, thanks for your comments, I noticed that not all of you understanded my question. But some did, and with their help I have now these two class functions:

template<class T> void read(T& value)
{
    event::deserialize(value, *this);
}

template<class T> T read()
{
    T temp;
    event::deserialize(temp, *this);
    return temp;
}

Note that these functions are members of a class named Stream.

Thank you for your help!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.