How can I accept both rvalue and lvalue non-const parameter type












2















I'm repeatedly running into the problem of accepting a non-const reference parameter, since it seems taking an rvalue parameter prevents accepting lvalues and vice versa. Here's an example



void read(File &file)// I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//readInto is a non-const method
// do something with the data populated in someObject
}


But when I try to call read I have a problem if I try two different calling conventions



//this works just fine
File f1 = File::open("some_file_path");
read(f1);

// However this fails
read( File::open("some_file_path") );//because open returns an rvalue


The problem I have is if I change the parameter to a non-const rvalue than I can't pass the lvalue anymore. Am I doomed to always provide an override (or template) that takes the rvalue reference type and simply calls out to the lvalue override?










share|improve this question

























  • Possible duplicate of How come a non-const reference cannot bind to a temporary object?

    – md5i
    Nov 22 '18 at 5:01
















2















I'm repeatedly running into the problem of accepting a non-const reference parameter, since it seems taking an rvalue parameter prevents accepting lvalues and vice versa. Here's an example



void read(File &file)// I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//readInto is a non-const method
// do something with the data populated in someObject
}


But when I try to call read I have a problem if I try two different calling conventions



//this works just fine
File f1 = File::open("some_file_path");
read(f1);

// However this fails
read( File::open("some_file_path") );//because open returns an rvalue


The problem I have is if I change the parameter to a non-const rvalue than I can't pass the lvalue anymore. Am I doomed to always provide an override (or template) that takes the rvalue reference type and simply calls out to the lvalue override?










share|improve this question

























  • Possible duplicate of How come a non-const reference cannot bind to a temporary object?

    – md5i
    Nov 22 '18 at 5:01














2












2








2








I'm repeatedly running into the problem of accepting a non-const reference parameter, since it seems taking an rvalue parameter prevents accepting lvalues and vice versa. Here's an example



void read(File &file)// I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//readInto is a non-const method
// do something with the data populated in someObject
}


But when I try to call read I have a problem if I try two different calling conventions



//this works just fine
File f1 = File::open("some_file_path");
read(f1);

// However this fails
read( File::open("some_file_path") );//because open returns an rvalue


The problem I have is if I change the parameter to a non-const rvalue than I can't pass the lvalue anymore. Am I doomed to always provide an override (or template) that takes the rvalue reference type and simply calls out to the lvalue override?










share|improve this question
















I'm repeatedly running into the problem of accepting a non-const reference parameter, since it seems taking an rvalue parameter prevents accepting lvalues and vice versa. Here's an example



void read(File &file)// I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//readInto is a non-const method
// do something with the data populated in someObject
}


But when I try to call read I have a problem if I try two different calling conventions



//this works just fine
File f1 = File::open("some_file_path");
read(f1);

// However this fails
read( File::open("some_file_path") );//because open returns an rvalue


The problem I have is if I change the parameter to a non-const rvalue than I can't pass the lvalue anymore. Am I doomed to always provide an override (or template) that takes the rvalue reference type and simply calls out to the lvalue override?







c++11 rvalue-reference pass-by-rvalue-reference






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 21 '18 at 23:07







xaviersjs

















asked Nov 21 '18 at 22:48









xaviersjsxaviersjs

5211716




5211716













  • Possible duplicate of How come a non-const reference cannot bind to a temporary object?

    – md5i
    Nov 22 '18 at 5:01



















  • Possible duplicate of How come a non-const reference cannot bind to a temporary object?

    – md5i
    Nov 22 '18 at 5:01

















Possible duplicate of How come a non-const reference cannot bind to a temporary object?

– md5i
Nov 22 '18 at 5:01





Possible duplicate of How come a non-const reference cannot bind to a temporary object?

– md5i
Nov 22 '18 at 5:01












1 Answer
1






active

oldest

votes


















1














Since you updated the question, I suggest doing this:



void read(File& file)
{
SomeClass someObject;
file.radInto(&someObject);
// ...
}

void read(File&& file) { read(file); }


That will handle both lvalues and rvalues with minimal code repetition.





I think your read function should simply take a File&:



void read(File& file) // I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}


Then you can call:



// OK
std::shared_ptr<File> f1 = File::open("some_file_path");
read(*f1);

// OK
read( *File::open("some_file_path") );


Added benefit: the function is not limited to shared_ptr, and works with any File independently of how its memory is managed.





Alternatively, use a forwarding reference:



template <typename T>
void read(T&& file)// I want to modify file
{
SomeClass someObject;
file->readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}





share|improve this answer


























  • You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

    – xaviersjs
    Nov 21 '18 at 23:09











  • @xaviersjs: I updated my answer.

    – Vittorio Romeo
    Nov 22 '18 at 10:37











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421505%2fhow-can-i-accept-both-rvalue-and-lvalue-non-const-parameter-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Since you updated the question, I suggest doing this:



void read(File& file)
{
SomeClass someObject;
file.radInto(&someObject);
// ...
}

void read(File&& file) { read(file); }


That will handle both lvalues and rvalues with minimal code repetition.





I think your read function should simply take a File&:



void read(File& file) // I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}


Then you can call:



// OK
std::shared_ptr<File> f1 = File::open("some_file_path");
read(*f1);

// OK
read( *File::open("some_file_path") );


Added benefit: the function is not limited to shared_ptr, and works with any File independently of how its memory is managed.





Alternatively, use a forwarding reference:



template <typename T>
void read(T&& file)// I want to modify file
{
SomeClass someObject;
file->readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}





share|improve this answer


























  • You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

    – xaviersjs
    Nov 21 '18 at 23:09











  • @xaviersjs: I updated my answer.

    – Vittorio Romeo
    Nov 22 '18 at 10:37
















1














Since you updated the question, I suggest doing this:



void read(File& file)
{
SomeClass someObject;
file.radInto(&someObject);
// ...
}

void read(File&& file) { read(file); }


That will handle both lvalues and rvalues with minimal code repetition.





I think your read function should simply take a File&:



void read(File& file) // I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}


Then you can call:



// OK
std::shared_ptr<File> f1 = File::open("some_file_path");
read(*f1);

// OK
read( *File::open("some_file_path") );


Added benefit: the function is not limited to shared_ptr, and works with any File independently of how its memory is managed.





Alternatively, use a forwarding reference:



template <typename T>
void read(T&& file)// I want to modify file
{
SomeClass someObject;
file->readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}





share|improve this answer


























  • You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

    – xaviersjs
    Nov 21 '18 at 23:09











  • @xaviersjs: I updated my answer.

    – Vittorio Romeo
    Nov 22 '18 at 10:37














1












1








1







Since you updated the question, I suggest doing this:



void read(File& file)
{
SomeClass someObject;
file.radInto(&someObject);
// ...
}

void read(File&& file) { read(file); }


That will handle both lvalues and rvalues with minimal code repetition.





I think your read function should simply take a File&:



void read(File& file) // I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}


Then you can call:



// OK
std::shared_ptr<File> f1 = File::open("some_file_path");
read(*f1);

// OK
read( *File::open("some_file_path") );


Added benefit: the function is not limited to shared_ptr, and works with any File independently of how its memory is managed.





Alternatively, use a forwarding reference:



template <typename T>
void read(T&& file)// I want to modify file
{
SomeClass someObject;
file->readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}





share|improve this answer















Since you updated the question, I suggest doing this:



void read(File& file)
{
SomeClass someObject;
file.radInto(&someObject);
// ...
}

void read(File&& file) { read(file); }


That will handle both lvalues and rvalues with minimal code repetition.





I think your read function should simply take a File&:



void read(File& file) // I want to modify file
{
SomeClass someObject;
file.readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}


Then you can call:



// OK
std::shared_ptr<File> f1 = File::open("some_file_path");
read(*f1);

// OK
read( *File::open("some_file_path") );


Added benefit: the function is not limited to shared_ptr, and works with any File independently of how its memory is managed.





Alternatively, use a forwarding reference:



template <typename T>
void read(T&& file)// I want to modify file
{
SomeClass someObject;
file->readInto(&someObject);//Modifies file
// do something with the data populated in someObject
}






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 22 '18 at 10:37

























answered Nov 21 '18 at 22:51









Vittorio RomeoVittorio Romeo

58.3k17158300




58.3k17158300













  • You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

    – xaviersjs
    Nov 21 '18 at 23:09











  • @xaviersjs: I updated my answer.

    – Vittorio Romeo
    Nov 22 '18 at 10:37



















  • You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

    – xaviersjs
    Nov 21 '18 at 23:09











  • @xaviersjs: I updated my answer.

    – Vittorio Romeo
    Nov 22 '18 at 10:37

















You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

– xaviersjs
Nov 21 '18 at 23:09





You're right. I updated the question to delete the shared_ptr part, but the question remains the same.

– xaviersjs
Nov 21 '18 at 23:09













@xaviersjs: I updated my answer.

– Vittorio Romeo
Nov 22 '18 at 10:37





@xaviersjs: I updated my answer.

– Vittorio Romeo
Nov 22 '18 at 10:37




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53421505%2fhow-can-i-accept-both-rvalue-and-lvalue-non-const-parameter-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith