Why does type aliasing determine whether output is L-value or R-value?
up vote
3
down vote
favorite
I created a struct with two static functions for testing purposes. The first instance of f
is called when an l-value reference
is passed. The second instance is called when an r-value
is passed:
template <typename _Tp>
struct T {
static constexpr void f(_Tp&) { std::cout << "f(T&) is called!n"; }
static constexpr void f(_Tp&&) { std::cout << "f(T&&) is called!n"; }
};
When I was experimenting with strong types
, I found out the first instance, T::f(_Tp&)
was called when I attempted to create the strong type implicitly. Why is this? (See following)
using T_int = T<int>;
T_int::f(
typename strong_types::create_strong_type<int, struct tag>(5)()
); // calls f::(T&) (?)
using KG = typename strong_types::create_strong_type<double, struct KG_tag>;
T_int::f(KG(4.2)()); // calls f(T&&)
Note that operator()
returns the value given through the constructor.
Feel free to ask if I need to elaborate.
EDIT: strong_types
is a namespace. It exists among other things of the alias create_strong_type
:
namespace strong_type {
template <typename T, typename tag>
using create_strong_type = Strong_Type<T, tag>;
...
}
...
template <typename T, typename tag>
struct Strong_Type {
constexpr explicit Strong_Type(const T& value) : _value(value) {}
constexpr explicit Strong_Type(T&& value) : _value(std::move(value)) {}
constexpr T& operator()() noexcept { return _value; }
private:
T _value;
};
c++ reference c++14 lvalue type-alias
|
show 3 more comments
up vote
3
down vote
favorite
I created a struct with two static functions for testing purposes. The first instance of f
is called when an l-value reference
is passed. The second instance is called when an r-value
is passed:
template <typename _Tp>
struct T {
static constexpr void f(_Tp&) { std::cout << "f(T&) is called!n"; }
static constexpr void f(_Tp&&) { std::cout << "f(T&&) is called!n"; }
};
When I was experimenting with strong types
, I found out the first instance, T::f(_Tp&)
was called when I attempted to create the strong type implicitly. Why is this? (See following)
using T_int = T<int>;
T_int::f(
typename strong_types::create_strong_type<int, struct tag>(5)()
); // calls f::(T&) (?)
using KG = typename strong_types::create_strong_type<double, struct KG_tag>;
T_int::f(KG(4.2)()); // calls f(T&&)
Note that operator()
returns the value given through the constructor.
Feel free to ask if I need to elaborate.
EDIT: strong_types
is a namespace. It exists among other things of the alias create_strong_type
:
namespace strong_type {
template <typename T, typename tag>
using create_strong_type = Strong_Type<T, tag>;
...
}
...
template <typename T, typename tag>
struct Strong_Type {
constexpr explicit Strong_Type(const T& value) : _value(value) {}
constexpr explicit Strong_Type(T&& value) : _value(std::move(value)) {}
constexpr T& operator()() noexcept { return _value; }
private:
T _value;
};
c++ reference c++14 lvalue type-alias
3
what isstrong_types
?
– Piotr Skotnicki
Nov 19 at 17:32
Sure, but is it a third party library ?
– Piotr Skotnicki
Nov 19 at 17:40
Oo, I am sorry for my misunderstanding.strong_types
is a namespace I created myself.
– Lourens Dijkstra
Nov 19 at 17:41
1
Also unrelated: Identifiers beginning with underscore, followed by uppercase letter are reserved and you are not allowed to use them.
– user10605163
Nov 19 at 17:45
1
Please fix the typos in your edits, the identifiers do not match, e.g.strong_type
vsstrong_types
andStrong_Type
and probablyStrong_Type
should be part of the namespace and beforecreate_strong_type
?. It doesn't compile the way it is even if generously moving around code.
– user10605163
Nov 19 at 17:51
|
show 3 more comments
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I created a struct with two static functions for testing purposes. The first instance of f
is called when an l-value reference
is passed. The second instance is called when an r-value
is passed:
template <typename _Tp>
struct T {
static constexpr void f(_Tp&) { std::cout << "f(T&) is called!n"; }
static constexpr void f(_Tp&&) { std::cout << "f(T&&) is called!n"; }
};
When I was experimenting with strong types
, I found out the first instance, T::f(_Tp&)
was called when I attempted to create the strong type implicitly. Why is this? (See following)
using T_int = T<int>;
T_int::f(
typename strong_types::create_strong_type<int, struct tag>(5)()
); // calls f::(T&) (?)
using KG = typename strong_types::create_strong_type<double, struct KG_tag>;
T_int::f(KG(4.2)()); // calls f(T&&)
Note that operator()
returns the value given through the constructor.
Feel free to ask if I need to elaborate.
EDIT: strong_types
is a namespace. It exists among other things of the alias create_strong_type
:
namespace strong_type {
template <typename T, typename tag>
using create_strong_type = Strong_Type<T, tag>;
...
}
...
template <typename T, typename tag>
struct Strong_Type {
constexpr explicit Strong_Type(const T& value) : _value(value) {}
constexpr explicit Strong_Type(T&& value) : _value(std::move(value)) {}
constexpr T& operator()() noexcept { return _value; }
private:
T _value;
};
c++ reference c++14 lvalue type-alias
I created a struct with two static functions for testing purposes. The first instance of f
is called when an l-value reference
is passed. The second instance is called when an r-value
is passed:
template <typename _Tp>
struct T {
static constexpr void f(_Tp&) { std::cout << "f(T&) is called!n"; }
static constexpr void f(_Tp&&) { std::cout << "f(T&&) is called!n"; }
};
When I was experimenting with strong types
, I found out the first instance, T::f(_Tp&)
was called when I attempted to create the strong type implicitly. Why is this? (See following)
using T_int = T<int>;
T_int::f(
typename strong_types::create_strong_type<int, struct tag>(5)()
); // calls f::(T&) (?)
using KG = typename strong_types::create_strong_type<double, struct KG_tag>;
T_int::f(KG(4.2)()); // calls f(T&&)
Note that operator()
returns the value given through the constructor.
Feel free to ask if I need to elaborate.
EDIT: strong_types
is a namespace. It exists among other things of the alias create_strong_type
:
namespace strong_type {
template <typename T, typename tag>
using create_strong_type = Strong_Type<T, tag>;
...
}
...
template <typename T, typename tag>
struct Strong_Type {
constexpr explicit Strong_Type(const T& value) : _value(value) {}
constexpr explicit Strong_Type(T&& value) : _value(std::move(value)) {}
constexpr T& operator()() noexcept { return _value; }
private:
T _value;
};
c++ reference c++14 lvalue type-alias
c++ reference c++14 lvalue type-alias
edited Nov 19 at 17:57
asked Nov 19 at 16:57
Lourens Dijkstra
769
769
3
what isstrong_types
?
– Piotr Skotnicki
Nov 19 at 17:32
Sure, but is it a third party library ?
– Piotr Skotnicki
Nov 19 at 17:40
Oo, I am sorry for my misunderstanding.strong_types
is a namespace I created myself.
– Lourens Dijkstra
Nov 19 at 17:41
1
Also unrelated: Identifiers beginning with underscore, followed by uppercase letter are reserved and you are not allowed to use them.
– user10605163
Nov 19 at 17:45
1
Please fix the typos in your edits, the identifiers do not match, e.g.strong_type
vsstrong_types
andStrong_Type
and probablyStrong_Type
should be part of the namespace and beforecreate_strong_type
?. It doesn't compile the way it is even if generously moving around code.
– user10605163
Nov 19 at 17:51
|
show 3 more comments
3
what isstrong_types
?
– Piotr Skotnicki
Nov 19 at 17:32
Sure, but is it a third party library ?
– Piotr Skotnicki
Nov 19 at 17:40
Oo, I am sorry for my misunderstanding.strong_types
is a namespace I created myself.
– Lourens Dijkstra
Nov 19 at 17:41
1
Also unrelated: Identifiers beginning with underscore, followed by uppercase letter are reserved and you are not allowed to use them.
– user10605163
Nov 19 at 17:45
1
Please fix the typos in your edits, the identifiers do not match, e.g.strong_type
vsstrong_types
andStrong_Type
and probablyStrong_Type
should be part of the namespace and beforecreate_strong_type
?. It doesn't compile the way it is even if generously moving around code.
– user10605163
Nov 19 at 17:51
3
3
what is
strong_types
?– Piotr Skotnicki
Nov 19 at 17:32
what is
strong_types
?– Piotr Skotnicki
Nov 19 at 17:32
Sure, but is it a third party library ?
– Piotr Skotnicki
Nov 19 at 17:40
Sure, but is it a third party library ?
– Piotr Skotnicki
Nov 19 at 17:40
Oo, I am sorry for my misunderstanding.
strong_types
is a namespace I created myself.– Lourens Dijkstra
Nov 19 at 17:41
Oo, I am sorry for my misunderstanding.
strong_types
is a namespace I created myself.– Lourens Dijkstra
Nov 19 at 17:41
1
1
Also unrelated: Identifiers beginning with underscore, followed by uppercase letter are reserved and you are not allowed to use them.
– user10605163
Nov 19 at 17:45
Also unrelated: Identifiers beginning with underscore, followed by uppercase letter are reserved and you are not allowed to use them.
– user10605163
Nov 19 at 17:45
1
1
Please fix the typos in your edits, the identifiers do not match, e.g.
strong_type
vs strong_types
and Strong_Type
and probably Strong_Type
should be part of the namespace and before create_strong_type
?. It doesn't compile the way it is even if generously moving around code.– user10605163
Nov 19 at 17:51
Please fix the typos in your edits, the identifiers do not match, e.g.
strong_type
vs strong_types
and Strong_Type
and probably Strong_Type
should be part of the namespace and before create_strong_type
?. It doesn't compile the way it is even if generously moving around code.– user10605163
Nov 19 at 17:51
|
show 3 more comments
1 Answer
1
active
oldest
votes
up vote
1
down vote
accepted
The difference is not due to using an alias (using
), but to the type you pass as first template argument to create_strong_type
. In one case, it's an int
, and in the other, a double
.
Try T<double>::f(KG(4.2)());
and you will see the argument is passed as lvalue reference (because of the return type of Strong_Type::operator()
, which is T&
).
add a comment |
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',
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53379373%2fwhy-does-type-aliasing-determine-whether-output-is-l-value-or-r-value%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
up vote
1
down vote
accepted
The difference is not due to using an alias (using
), but to the type you pass as first template argument to create_strong_type
. In one case, it's an int
, and in the other, a double
.
Try T<double>::f(KG(4.2)());
and you will see the argument is passed as lvalue reference (because of the return type of Strong_Type::operator()
, which is T&
).
add a comment |
up vote
1
down vote
accepted
The difference is not due to using an alias (using
), but to the type you pass as first template argument to create_strong_type
. In one case, it's an int
, and in the other, a double
.
Try T<double>::f(KG(4.2)());
and you will see the argument is passed as lvalue reference (because of the return type of Strong_Type::operator()
, which is T&
).
add a comment |
up vote
1
down vote
accepted
up vote
1
down vote
accepted
The difference is not due to using an alias (using
), but to the type you pass as first template argument to create_strong_type
. In one case, it's an int
, and in the other, a double
.
Try T<double>::f(KG(4.2)());
and you will see the argument is passed as lvalue reference (because of the return type of Strong_Type::operator()
, which is T&
).
The difference is not due to using an alias (using
), but to the type you pass as first template argument to create_strong_type
. In one case, it's an int
, and in the other, a double
.
Try T<double>::f(KG(4.2)());
and you will see the argument is passed as lvalue reference (because of the return type of Strong_Type::operator()
, which is T&
).
answered Nov 19 at 17:57
Nelfeal
4,170621
4,170621
add a comment |
add a comment |
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53379373%2fwhy-does-type-aliasing-determine-whether-output-is-l-value-or-r-value%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
3
what is
strong_types
?– Piotr Skotnicki
Nov 19 at 17:32
Sure, but is it a third party library ?
– Piotr Skotnicki
Nov 19 at 17:40
Oo, I am sorry for my misunderstanding.
strong_types
is a namespace I created myself.– Lourens Dijkstra
Nov 19 at 17:41
1
Also unrelated: Identifiers beginning with underscore, followed by uppercase letter are reserved and you are not allowed to use them.
– user10605163
Nov 19 at 17:45
1
Please fix the typos in your edits, the identifiers do not match, e.g.
strong_type
vsstrong_types
andStrong_Type
and probablyStrong_Type
should be part of the namespace and beforecreate_strong_type
?. It doesn't compile the way it is even if generously moving around code.– user10605163
Nov 19 at 17:51