Pass literal as const ref parameter


innocent bystander

Imagine the following simplified code:

#include <iostream>
void foo(const int& x) { do_something_with(x); }

int main() { foo(42); return 0; }

(1) Besides optimization, what happens when 42 is passed to foo?

Does the compiler stick 42 somewhere (on the stack?) and pass its address to foo?

(1a) Is the action to be taken in this case specified in the standard (or is it strictly up to the compiler)?


Now, imagine slightly different code:

#include <iostream>
void foo(const int& x) { do_something_with(x); }

struct bar { static constexpr int baz = 42; };

int main() { foo(bar::baz); return 0; }

It won't link unless I define int bar::baz;(due to ODR?) .

(2) Besides ODR, why can't the compiler do the 42 above?


An obvious way to simplify things is to define fooas:

void foo(int x) { do_something_with(x); }

But what if there are templates? E.g:

template<typename T>
void foo(T&& x) { do_something_with(std::forward<T>(x)); }

(3) Is there an elegant way to tell primitive types to fooaccept by value x? Or do I need to specialize it using SFINAE or similar?

EDIT : Modified what happened inside fooas it was not relevant to this question.

TC

Does the compiler stick 42 somewhere (on the stack?) and pass its address to foo?

const intCreates an object of a temporary type , initialized with a prvalue expression 42, and bound to a reference.

In practice, if foonot inlined, you need to allocate space on the stack, store 42it on the stack and pass the address.

Is there anything in the standard that dictates what to do in this case (or is it strictly up to the compiler)?

[dcl.init.ref]

Why can't the compiler do anything with the 42 above other than the ODR?

Because according to the language, references are bound to objects bar::baz, and unless the compiler knows exactly what foois being done when the compile call is made, it must assume that makes sense. For example, if foocontained assert(&x == &bar::baz);, it must not fire foo(bar::baz).

(In C++17, bazis implicitly inlined as a constexprstatic data member ; no separate definition is required.)

Is there an elegant way to tell fooyou to accept xvalues ​​of primitive types?

It usually doesn't make much sense to do this without profiling data to show that pass-by-reference is actually causing problems, but if it is really needed for some reason, adding a (possibly SFINAE-bound) overload would be the way to go road.

Related


Is a const int ref in a constructor safe to bind to a literal?

Ryan Haining I know the standard has an exception for extending the lifetime of temporary objects, which basically says that binding a const reference in a constructor doesn't extend the lifetime, but does that apply to literals as well? E.g: class C { pri

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Is the [Ref] attribute of a const record parameter useful?

username With the latest Delphi version (Berlin/10.1/24), is the [Ref] attribute really necessary? I'm asking this because the online documentation says: Constant parameters can be passed to functions by value or by reference, depending on the specific compile

cannot pass 'const pointer const' to const ref

Thomas B. Suppose you have a set of pointers (yes...): std::set<SomeType*> myTypeContainer; Then suppose you want to search this collection from a const method of SomeType: bool SomeType::IsContainered() const { return myTypeContainer.find(this) != myType

function template specialization with const ref parameter

use The following code compiles fine . #include <iostream> struct rgb8{ uint8_t r() const {return 0;}; }; template<typename L, typename P> L pixelToLevel(P p) { return static_cast<L>(p); } template<> uint8_t pixelToLevel<uint8_t, rgb8>(rgb8 p) { /

Is a const int ref in a constructor safe to bind to a literal?

Ryan Haining I know the standard has an exception for extending the lifetime of temporary objects, which basically says that binding a const reference in a constructor doesn't extend the lifetime, but does that apply to literals as well? E.g: class C { pri

Pass pointer to const ref function

Dean Why does the following work? #include <iostream> using namespace std; class PolyLine { public: PolyLine() = default; PolyLine(PolyLine * ptr) { std::cout << "Ctor called" << std::endl; } }; void function(const PolyLine& pt) { } int main() {

Is the [Ref] attribute of a const record parameter useful?

username With the latest Delphi version (Berlin/10.1/24), is the [Ref] attribute really necessary? I'm asking this because the online documentation says: Constant parameters can be passed to functions by value or by reference, depending on the specific compile

Pass literal as const ref parameter

innocent bystander Imagine the following simplified code: #include <iostream> void foo(const int& x) { do_something_with(x); } int main() { foo(42); return 0; } (1) Besides optimization, what happens when 42 is passed to foo? Does the compiler stick 42 somew

Pass literal as const ref parameter

innocent bystander Imagine the following simplified code: #include <iostream> void foo(const int& x) { do_something_with(x); } int main() { foo(42); return 0; } (1) Besides optimization, what happens when 42 is passed to foo? Does the compiler stick 42 somew

cannot pass 'const pointer const' to const ref

Thomas B. Suppose you have a set of pointers (yes...): std::set<SomeType*> myTypeContainer; Then suppose you want to search this collection from a const method of SomeType: bool SomeType::IsContainered() const { return myTypeContainer.find(this) != myType

Is the [Ref] attribute of a const record parameter useful?

username With the latest Delphi version (Berlin/10.1/24), is the [Ref] attribute really necessary? I'm asking this because the online documentation says: Constant parameters can be passed to functions by value or by reference, depending on the specific compile

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

Typescript - pass interface literal to function parameter

Paul Redmond I want to use an interface to set data types and then call them in a function while setting default values without passing the data . I am getting the after canvas error ',' expected.in the function . Can't I call it that? // Options interface opt

function template specialization with const ref parameter

use The following code compiles fine . #include <iostream> struct rgb8{ uint8_t r() const {return 0;}; }; template<typename L, typename P> L pixelToLevel(P p) { return static_cast<L>(p); } template<> uint8_t pixelToLevel<uint8_t, rgb8>(rgb8 p) { /

Pass pointer by value or const ref?

Barry In short, is it better to pass pointers by value or const reference? I wrote a simple function to explore: void foo(int* v) { std::cout << *v << endl; } and void foo(int* const& v) { std::cout << *v << endl; } I tried looking at the generated assembly,

Pass parameter to $ref in OpenAPI 3

some development Suppose I have the following schema for later use $ref: "schemas": { "Order": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "petI

function template specialization with const ref parameter

use The following code compiles fine . #include <iostream> struct rgb8{ uint8_t r() const {return 0;}; }; template<typename L, typename P> L pixelToLevel(P p) { return static_cast<L>(p); } template<> uint8_t pixelToLevel<uint8_t, rgb8>(rgb8 p) { /

Is a const int ref in a constructor safe to bind to a literal?

Ryan Haining I know the standard has an exception for extending the lifetime of temporary objects, which basically says that binding a const reference in a constructor doesn't extend the lifetime, but does that apply to literals as well? E.g: class C { pri

Is the [Ref] attribute of a const record parameter useful?

username With the latest Delphi version (Berlin/10.1/24), is the [Ref] attribute really necessary? I'm asking this because the online documentation says: Constant parameters can be passed to functions by value or by reference, depending on the specific compile

Is the [Ref] attribute of a const record parameter useful?

username With the latest Delphi version (Berlin/10.1/24), is the [Ref] attribute really necessary? I'm asking this because the online documentation says: Constant parameters can be passed to functions by value or by reference, depending on the specific compile

Pass literal as const ref parameter

innocent bystander Imagine the following simplified code: #include <iostream> void foo(const int& x) { do_something_with(x); } int main() { foo(42); return 0; } (1) Besides optimization, what happens when 42 is passed to foo? Does the compiler stick 42 somew

Pass literal as const ref parameter

innocent bystander Imagine the following simplified code: #include <iostream> void foo(const int& x) { do_something_with(x); } int main() { foo(42); return 0; } (1) Besides optimization, what happens when 42 is passed to foo? Does the compiler stick 42 somew

cannot pass 'const pointer const' to const ref

Thomas B. Suppose you have a set of pointers (yes...): std::set<SomeType*> myTypeContainer; Then suppose you want to search this collection from a const method of SomeType: bool SomeType::IsContainered() const { return myTypeContainer.find(this) != myType

Pass parameter to $ref in OpenAPI 3

some development Suppose I have the following schema for later use $ref: "schemas": { "Order": { "type": "object", "properties": { "id": { "type": "integer", "format": "int64" }, "petI

function template specialization with const ref parameter

use The following code compiles fine . #include <iostream> struct rgb8{ uint8_t r() const {return 0;}; }; template<typename L, typename P> L pixelToLevel(P p) { return static_cast<L>(p); } template<> uint8_t pixelToLevel<uint8_t, rgb8>(rgb8 p) { /

Python pass ref int as parameter

Mr. Sha The tlb library in my python project passes win32com.client. I've easily used a number of built-in functions, but one of the main functions takes a list of arguments for two of them marked as ref int. When I try to pass a python integer to the function