How to make set(args…) method?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
For example, I have a class
class A
public:
template<class T, class... Args>
void set(Args&&... args);
private:
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2; // Member types are all different.
;
And I hope I can use it as
A a;
a.set<Member1Type>(args... to construct Member1Type);
which like
make_shared<T>(args...);
My question is how to link member type to the correct member in implementing the method. Thanks!
c++ c++11 templates c++14
add a comment |
For example, I have a class
class A
public:
template<class T, class... Args>
void set(Args&&... args);
private:
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2; // Member types are all different.
;
And I hope I can use it as
A a;
a.set<Member1Type>(args... to construct Member1Type);
which like
make_shared<T>(args...);
My question is how to link member type to the correct member in implementing the method. Thanks!
c++ c++11 templates c++14
You could provide a pointer to data member toset
to tell it which member to set. But to do that you would need to expose the members, including their underlying type at which point there isn't really any point in trying to encapsulate it with a setter.
– François Andrieux
Nov 15 '18 at 15:17
add a comment |
For example, I have a class
class A
public:
template<class T, class... Args>
void set(Args&&... args);
private:
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2; // Member types are all different.
;
And I hope I can use it as
A a;
a.set<Member1Type>(args... to construct Member1Type);
which like
make_shared<T>(args...);
My question is how to link member type to the correct member in implementing the method. Thanks!
c++ c++11 templates c++14
For example, I have a class
class A
public:
template<class T, class... Args>
void set(Args&&... args);
private:
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2; // Member types are all different.
;
And I hope I can use it as
A a;
a.set<Member1Type>(args... to construct Member1Type);
which like
make_shared<T>(args...);
My question is how to link member type to the correct member in implementing the method. Thanks!
c++ c++11 templates c++14
c++ c++11 templates c++14
edited Nov 15 '18 at 15:12
HolyBlackCat
17.3k33568
17.3k33568
asked Nov 15 '18 at 15:08
user1899020user1899020
5,5551249105
5,5551249105
You could provide a pointer to data member toset
to tell it which member to set. But to do that you would need to expose the members, including their underlying type at which point there isn't really any point in trying to encapsulate it with a setter.
– François Andrieux
Nov 15 '18 at 15:17
add a comment |
You could provide a pointer to data member toset
to tell it which member to set. But to do that you would need to expose the members, including their underlying type at which point there isn't really any point in trying to encapsulate it with a setter.
– François Andrieux
Nov 15 '18 at 15:17
You could provide a pointer to data member to
set
to tell it which member to set. But to do that you would need to expose the members, including their underlying type at which point there isn't really any point in trying to encapsulate it with a setter.– François Andrieux
Nov 15 '18 at 15:17
You could provide a pointer to data member to
set
to tell it which member to set. But to do that you would need to expose the members, including their underlying type at which point there isn't really any point in trying to encapsulate it with a setter.– François Andrieux
Nov 15 '18 at 15:17
add a comment |
3 Answers
3
active
oldest
votes
I'd populate a std::tuple<MemberType1*, MemberType2*, ...>
in the ctor, so you can then use get<T*>(m_tuple)
in A::set<T, Args...>
[edit]
Or as StoryTeller suggested, without extra members:
private:
std::tuple <
std::shared_ptr<Member1Type>,
std::shared_ptr<Member2Type>
> m_members;
You'd now need std::get<std::shared_ptr<T>>(m_members)
Nice use oftuple
. But why the switch to raw pointers?
– StoryTeller
Nov 15 '18 at 15:16
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign thetuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.
– François Andrieux
Nov 15 '18 at 15:20
@StoryTeller: Ah, I see what you're getting at. My logic was thatm_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.
– MSalters
Nov 15 '18 at 15:21
@MSalters If the raw pointer's lifetime is coupled to an existingshared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to theshared_ptr<T>*
instead to allow you to assign to it.
– François Andrieux
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argumentT
ofset<T, Args...>
.
– MSalters
Nov 15 '18 at 15:22
|
show 2 more comments
If you don't want to go the tuple
approach, one way you could do this is to provide private getters for each member, overloaded on a tag type:
template <typename T> struct type_t ;
template <typename T> constexpr type_t<T> type;
class A
public:
template<class T, class... Args>
void set(Args&&... args)
get(type<T>) = std::make_shared<T>(std::forward<Args>(args)...);
private:
auto& get(type_t<Member1Type>) return m_member1;
auto& get(type_t<Member2Type>) return m_member2;
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2;
;
The auto&
return avoids the need to write the type again, which already appears in the parameter list (kind of the same way you wouldn't repeat the type when writing a C++ cast).
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
add a comment |
[enter link description here][۱
**
**strong
**
1: http://www.google play.com
enter code here
quote
- [List item][۱]
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',
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
);
);
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%2f53322393%2fhow-to-make-settargs-method%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
I'd populate a std::tuple<MemberType1*, MemberType2*, ...>
in the ctor, so you can then use get<T*>(m_tuple)
in A::set<T, Args...>
[edit]
Or as StoryTeller suggested, without extra members:
private:
std::tuple <
std::shared_ptr<Member1Type>,
std::shared_ptr<Member2Type>
> m_members;
You'd now need std::get<std::shared_ptr<T>>(m_members)
Nice use oftuple
. But why the switch to raw pointers?
– StoryTeller
Nov 15 '18 at 15:16
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign thetuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.
– François Andrieux
Nov 15 '18 at 15:20
@StoryTeller: Ah, I see what you're getting at. My logic was thatm_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.
– MSalters
Nov 15 '18 at 15:21
@MSalters If the raw pointer's lifetime is coupled to an existingshared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to theshared_ptr<T>*
instead to allow you to assign to it.
– François Andrieux
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argumentT
ofset<T, Args...>
.
– MSalters
Nov 15 '18 at 15:22
|
show 2 more comments
I'd populate a std::tuple<MemberType1*, MemberType2*, ...>
in the ctor, so you can then use get<T*>(m_tuple)
in A::set<T, Args...>
[edit]
Or as StoryTeller suggested, without extra members:
private:
std::tuple <
std::shared_ptr<Member1Type>,
std::shared_ptr<Member2Type>
> m_members;
You'd now need std::get<std::shared_ptr<T>>(m_members)
Nice use oftuple
. But why the switch to raw pointers?
– StoryTeller
Nov 15 '18 at 15:16
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign thetuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.
– François Andrieux
Nov 15 '18 at 15:20
@StoryTeller: Ah, I see what you're getting at. My logic was thatm_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.
– MSalters
Nov 15 '18 at 15:21
@MSalters If the raw pointer's lifetime is coupled to an existingshared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to theshared_ptr<T>*
instead to allow you to assign to it.
– François Andrieux
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argumentT
ofset<T, Args...>
.
– MSalters
Nov 15 '18 at 15:22
|
show 2 more comments
I'd populate a std::tuple<MemberType1*, MemberType2*, ...>
in the ctor, so you can then use get<T*>(m_tuple)
in A::set<T, Args...>
[edit]
Or as StoryTeller suggested, without extra members:
private:
std::tuple <
std::shared_ptr<Member1Type>,
std::shared_ptr<Member2Type>
> m_members;
You'd now need std::get<std::shared_ptr<T>>(m_members)
I'd populate a std::tuple<MemberType1*, MemberType2*, ...>
in the ctor, so you can then use get<T*>(m_tuple)
in A::set<T, Args...>
[edit]
Or as StoryTeller suggested, without extra members:
private:
std::tuple <
std::shared_ptr<Member1Type>,
std::shared_ptr<Member2Type>
> m_members;
You'd now need std::get<std::shared_ptr<T>>(m_members)
edited Nov 15 '18 at 16:51
answered Nov 15 '18 at 15:14
MSaltersMSalters
135k8119271
135k8119271
Nice use oftuple
. But why the switch to raw pointers?
– StoryTeller
Nov 15 '18 at 15:16
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign thetuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.
– François Andrieux
Nov 15 '18 at 15:20
@StoryTeller: Ah, I see what you're getting at. My logic was thatm_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.
– MSalters
Nov 15 '18 at 15:21
@MSalters If the raw pointer's lifetime is coupled to an existingshared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to theshared_ptr<T>*
instead to allow you to assign to it.
– François Andrieux
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argumentT
ofset<T, Args...>
.
– MSalters
Nov 15 '18 at 15:22
|
show 2 more comments
Nice use oftuple
. But why the switch to raw pointers?
– StoryTeller
Nov 15 '18 at 15:16
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign thetuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.
– François Andrieux
Nov 15 '18 at 15:20
@StoryTeller: Ah, I see what you're getting at. My logic was thatm_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.
– MSalters
Nov 15 '18 at 15:21
@MSalters If the raw pointer's lifetime is coupled to an existingshared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to theshared_ptr<T>*
instead to allow you to assign to it.
– François Andrieux
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argumentT
ofset<T, Args...>
.
– MSalters
Nov 15 '18 at 15:22
Nice use of
tuple
. But why the switch to raw pointers?– StoryTeller
Nov 15 '18 at 15:16
Nice use of
tuple
. But why the switch to raw pointers?– StoryTeller
Nov 15 '18 at 15:16
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign the
tuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.– François Andrieux
Nov 15 '18 at 15:20
Note that this only works if each member has a different type and invalidates the compiler generated constructors and assignment operators. They would copy or assign the
tuple
which would point to the referenced instance's members instead of the assigned or constructed instance's.– François Andrieux
Nov 15 '18 at 15:20
@StoryTeller: Ah, I see what you're getting at. My logic was that
m_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.– MSalters
Nov 15 '18 at 15:21
@StoryTeller: Ah, I see what you're getting at. My logic was that
m_member1
might be an empty shared_ptr so I couldn't use references. But you can do away with the individual members, and store the shared_ptr directly in the tuple.– MSalters
Nov 15 '18 at 15:21
@MSalters If the raw pointer's lifetime is coupled to an existing
shared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to the shared_ptr<T>*
instead to allow you to assign to it.– François Andrieux
Nov 15 '18 at 15:22
@MSalters If the raw pointer's lifetime is coupled to an existing
shared_ptr
then there is no reason to share ownership.Raw pointers are perfectly fine when they aren't owning. Edit : Though you may want a tuple that points to the shared_ptr<T>*
instead to allow you to assign to it.– François Andrieux
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argument
T
of set<T, Args...>
.– MSalters
Nov 15 '18 at 15:22
@FrançoisAndrieux: The uniqueness is implied by the need to select the member by the single argument
T
of set<T, Args...>
.– MSalters
Nov 15 '18 at 15:22
|
show 2 more comments
If you don't want to go the tuple
approach, one way you could do this is to provide private getters for each member, overloaded on a tag type:
template <typename T> struct type_t ;
template <typename T> constexpr type_t<T> type;
class A
public:
template<class T, class... Args>
void set(Args&&... args)
get(type<T>) = std::make_shared<T>(std::forward<Args>(args)...);
private:
auto& get(type_t<Member1Type>) return m_member1;
auto& get(type_t<Member2Type>) return m_member2;
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2;
;
The auto&
return avoids the need to write the type again, which already appears in the parameter list (kind of the same way you wouldn't repeat the type when writing a C++ cast).
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
add a comment |
If you don't want to go the tuple
approach, one way you could do this is to provide private getters for each member, overloaded on a tag type:
template <typename T> struct type_t ;
template <typename T> constexpr type_t<T> type;
class A
public:
template<class T, class... Args>
void set(Args&&... args)
get(type<T>) = std::make_shared<T>(std::forward<Args>(args)...);
private:
auto& get(type_t<Member1Type>) return m_member1;
auto& get(type_t<Member2Type>) return m_member2;
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2;
;
The auto&
return avoids the need to write the type again, which already appears in the parameter list (kind of the same way you wouldn't repeat the type when writing a C++ cast).
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
add a comment |
If you don't want to go the tuple
approach, one way you could do this is to provide private getters for each member, overloaded on a tag type:
template <typename T> struct type_t ;
template <typename T> constexpr type_t<T> type;
class A
public:
template<class T, class... Args>
void set(Args&&... args)
get(type<T>) = std::make_shared<T>(std::forward<Args>(args)...);
private:
auto& get(type_t<Member1Type>) return m_member1;
auto& get(type_t<Member2Type>) return m_member2;
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2;
;
The auto&
return avoids the need to write the type again, which already appears in the parameter list (kind of the same way you wouldn't repeat the type when writing a C++ cast).
If you don't want to go the tuple
approach, one way you could do this is to provide private getters for each member, overloaded on a tag type:
template <typename T> struct type_t ;
template <typename T> constexpr type_t<T> type;
class A
public:
template<class T, class... Args>
void set(Args&&... args)
get(type<T>) = std::make_shared<T>(std::forward<Args>(args)...);
private:
auto& get(type_t<Member1Type>) return m_member1;
auto& get(type_t<Member2Type>) return m_member2;
std::shared_ptr<Member1Type> m_member1;
std::shared_ptr<Member2Type> m_member2;
;
The auto&
return avoids the need to write the type again, which already appears in the parameter list (kind of the same way you wouldn't repeat the type when writing a C++ cast).
answered Nov 15 '18 at 15:53
BarryBarry
187k21331610
187k21331610
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
add a comment |
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
I am wandering what the 2nd line is? A global variable?
– user1899020
Nov 15 '18 at 16:02
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
@user1899020 A variable template.
– Barry
Nov 15 '18 at 16:16
add a comment |
[enter link description here][۱
**
**strong
**
1: http://www.google play.com
enter code here
quote
- [List item][۱]
add a comment |
[enter link description here][۱
**
**strong
**
1: http://www.google play.com
enter code here
quote
- [List item][۱]
add a comment |
[enter link description here][۱
**
**strong
**
1: http://www.google play.com
enter code here
quote
- [List item][۱]
[enter link description here][۱
**
**strong
**
1: http://www.google play.com
enter code here
quote
- [List item][۱]
answered Dec 15 '18 at 12:41
user10794579user10794579
1
1
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.
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%2f53322393%2fhow-to-make-settargs-method%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
You could provide a pointer to data member to
set
to tell it which member to set. But to do that you would need to expose the members, including their underlying type at which point there isn't really any point in trying to encapsulate it with a setter.– François Andrieux
Nov 15 '18 at 15:17