How can I make a class agnostic of its members type?
I have a templated class
template <typename T>
class Templated {
T someValue;
//...
};
and another class with a member of type Templated.
class Holder {
Templated t;
//...
};
This would not compile, because actual type of Holder::Templated is not known. I want Holder::Templated to be initialized / created later, it's value and also type will be read from a configuration file. How can I create Holder objects but add the actual Holder::Templated members later?
I could have a base class to Templated and hold the base class pointer in the Holder class, but I don't like this option. Do you have any other ideas to keep the Holder class agnostic of the type of its Templated member?
Thank you very much!
c++ templates
add a comment |
I have a templated class
template <typename T>
class Templated {
T someValue;
//...
};
and another class with a member of type Templated.
class Holder {
Templated t;
//...
};
This would not compile, because actual type of Holder::Templated is not known. I want Holder::Templated to be initialized / created later, it's value and also type will be read from a configuration file. How can I create Holder objects but add the actual Holder::Templated members later?
I could have a base class to Templated and hold the base class pointer in the Holder class, but I don't like this option. Do you have any other ideas to keep the Holder class agnostic of the type of its Templated member?
Thank you very much!
c++ templates
4
You'll need some kind of type erasure then. If C++17 is an option, you might want to trystd::any.
– lubgr
Nov 20 at 14:16
1
You're out of luck. Templates are a compile-time feature. Polymorphism might be a better tool for your job.
– DeiDei
Nov 20 at 14:16
Thanks @lubgr, C++14 unfortunately. However you gave me a keyword to read about.
– lulijeta
Nov 20 at 14:48
add a comment |
I have a templated class
template <typename T>
class Templated {
T someValue;
//...
};
and another class with a member of type Templated.
class Holder {
Templated t;
//...
};
This would not compile, because actual type of Holder::Templated is not known. I want Holder::Templated to be initialized / created later, it's value and also type will be read from a configuration file. How can I create Holder objects but add the actual Holder::Templated members later?
I could have a base class to Templated and hold the base class pointer in the Holder class, but I don't like this option. Do you have any other ideas to keep the Holder class agnostic of the type of its Templated member?
Thank you very much!
c++ templates
I have a templated class
template <typename T>
class Templated {
T someValue;
//...
};
and another class with a member of type Templated.
class Holder {
Templated t;
//...
};
This would not compile, because actual type of Holder::Templated is not known. I want Holder::Templated to be initialized / created later, it's value and also type will be read from a configuration file. How can I create Holder objects but add the actual Holder::Templated members later?
I could have a base class to Templated and hold the base class pointer in the Holder class, but I don't like this option. Do you have any other ideas to keep the Holder class agnostic of the type of its Templated member?
Thank you very much!
c++ templates
c++ templates
asked Nov 20 at 14:13
lulijeta
419415
419415
4
You'll need some kind of type erasure then. If C++17 is an option, you might want to trystd::any.
– lubgr
Nov 20 at 14:16
1
You're out of luck. Templates are a compile-time feature. Polymorphism might be a better tool for your job.
– DeiDei
Nov 20 at 14:16
Thanks @lubgr, C++14 unfortunately. However you gave me a keyword to read about.
– lulijeta
Nov 20 at 14:48
add a comment |
4
You'll need some kind of type erasure then. If C++17 is an option, you might want to trystd::any.
– lubgr
Nov 20 at 14:16
1
You're out of luck. Templates are a compile-time feature. Polymorphism might be a better tool for your job.
– DeiDei
Nov 20 at 14:16
Thanks @lubgr, C++14 unfortunately. However you gave me a keyword to read about.
– lulijeta
Nov 20 at 14:48
4
4
You'll need some kind of type erasure then. If C++17 is an option, you might want to try
std::any.– lubgr
Nov 20 at 14:16
You'll need some kind of type erasure then. If C++17 is an option, you might want to try
std::any.– lubgr
Nov 20 at 14:16
1
1
You're out of luck. Templates are a compile-time feature. Polymorphism might be a better tool for your job.
– DeiDei
Nov 20 at 14:16
You're out of luck. Templates are a compile-time feature. Polymorphism might be a better tool for your job.
– DeiDei
Nov 20 at 14:16
Thanks @lubgr, C++14 unfortunately. However you gave me a keyword to read about.
– lulijeta
Nov 20 at 14:48
Thanks @lubgr, C++14 unfortunately. However you gave me a keyword to read about.
– lulijeta
Nov 20 at 14:48
add a comment |
3 Answers
3
active
oldest
votes
If you don't want to keep a pointer to templateds base class inside holder, you can add a layer of indirection and have templated itself hold a pointer to its concrete implementation.
class Holder {
Untemplated u;
//...
};
class Untemplated {
//...
struct Templated_base {
//... virtual interface
};
Templated_base* hook; // or better with smart pointers
template <typename T>
struct Templated : Templated_base {
// ... final interface
};
template <typename T>
Untemplated(T&& x) { hook = new Templated<T>(std::forward<T>(x)); }
};
This is only a rough sketch of an elaborate strategy devised by Sean Parent (see this: http://sean-parent.stlab.cc/papers-and-presentations/#better-code-runtime-polymorphism), which allows to use dynamic polymorphism somewhere without paying a price everywhere.
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
1
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
add a comment |
You can use std::any to hold a value of any type or std::variant to hold values from a set of types. E.g.:
#include <any>
class Holder {
std::any t;
//...
};
add a comment |
Templates are purely a compile-time polymorphism construct. You need run-time polymorphism, which can be achieved in many different ways in C++:
Inheritance +
virtualfunctions: useful when you have an interface and an open set of implementors;std::variant: useful when you have a known closed set of choices;std::any: useful when you want to store any arbitrary object without any restrictionMore:
std::function, dyno, ...
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%2f53394928%2fhow-can-i-make-a-class-agnostic-of-its-members-type%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
If you don't want to keep a pointer to templateds base class inside holder, you can add a layer of indirection and have templated itself hold a pointer to its concrete implementation.
class Holder {
Untemplated u;
//...
};
class Untemplated {
//...
struct Templated_base {
//... virtual interface
};
Templated_base* hook; // or better with smart pointers
template <typename T>
struct Templated : Templated_base {
// ... final interface
};
template <typename T>
Untemplated(T&& x) { hook = new Templated<T>(std::forward<T>(x)); }
};
This is only a rough sketch of an elaborate strategy devised by Sean Parent (see this: http://sean-parent.stlab.cc/papers-and-presentations/#better-code-runtime-polymorphism), which allows to use dynamic polymorphism somewhere without paying a price everywhere.
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
1
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
add a comment |
If you don't want to keep a pointer to templateds base class inside holder, you can add a layer of indirection and have templated itself hold a pointer to its concrete implementation.
class Holder {
Untemplated u;
//...
};
class Untemplated {
//...
struct Templated_base {
//... virtual interface
};
Templated_base* hook; // or better with smart pointers
template <typename T>
struct Templated : Templated_base {
// ... final interface
};
template <typename T>
Untemplated(T&& x) { hook = new Templated<T>(std::forward<T>(x)); }
};
This is only a rough sketch of an elaborate strategy devised by Sean Parent (see this: http://sean-parent.stlab.cc/papers-and-presentations/#better-code-runtime-polymorphism), which allows to use dynamic polymorphism somewhere without paying a price everywhere.
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
1
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
add a comment |
If you don't want to keep a pointer to templateds base class inside holder, you can add a layer of indirection and have templated itself hold a pointer to its concrete implementation.
class Holder {
Untemplated u;
//...
};
class Untemplated {
//...
struct Templated_base {
//... virtual interface
};
Templated_base* hook; // or better with smart pointers
template <typename T>
struct Templated : Templated_base {
// ... final interface
};
template <typename T>
Untemplated(T&& x) { hook = new Templated<T>(std::forward<T>(x)); }
};
This is only a rough sketch of an elaborate strategy devised by Sean Parent (see this: http://sean-parent.stlab.cc/papers-and-presentations/#better-code-runtime-polymorphism), which allows to use dynamic polymorphism somewhere without paying a price everywhere.
If you don't want to keep a pointer to templateds base class inside holder, you can add a layer of indirection and have templated itself hold a pointer to its concrete implementation.
class Holder {
Untemplated u;
//...
};
class Untemplated {
//...
struct Templated_base {
//... virtual interface
};
Templated_base* hook; // or better with smart pointers
template <typename T>
struct Templated : Templated_base {
// ... final interface
};
template <typename T>
Untemplated(T&& x) { hook = new Templated<T>(std::forward<T>(x)); }
};
This is only a rough sketch of an elaborate strategy devised by Sean Parent (see this: http://sean-parent.stlab.cc/papers-and-presentations/#better-code-runtime-polymorphism), which allows to use dynamic polymorphism somewhere without paying a price everywhere.
answered Nov 20 at 14:31
papagaga
482311
482311
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
1
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
add a comment |
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
1
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Thanks @papagaga, this one looks actually promising.
– lulijeta
Nov 20 at 14:48
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
Ah, was it really Sean Parent who devised it? He certainly presents it spectacularly, but devising the technique is quite an attribution.
– StoryTeller
Nov 20 at 15:07
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
@StoryTeller: you tell me the story then!
– papagaga
Nov 20 at 15:30
1
1
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@papagaga - You made the claim, so you back it up. That's where burden of proof is, not on me to disprove it.
– StoryTeller
Nov 20 at 15:36
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
@StoryTeller: here's my proof: citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.89.1257
– papagaga
Nov 20 at 15:53
add a comment |
You can use std::any to hold a value of any type or std::variant to hold values from a set of types. E.g.:
#include <any>
class Holder {
std::any t;
//...
};
add a comment |
You can use std::any to hold a value of any type or std::variant to hold values from a set of types. E.g.:
#include <any>
class Holder {
std::any t;
//...
};
add a comment |
You can use std::any to hold a value of any type or std::variant to hold values from a set of types. E.g.:
#include <any>
class Holder {
std::any t;
//...
};
You can use std::any to hold a value of any type or std::variant to hold values from a set of types. E.g.:
#include <any>
class Holder {
std::any t;
//...
};
answered Nov 20 at 14:19
Maxim Egorushkin
85.1k1199181
85.1k1199181
add a comment |
add a comment |
Templates are purely a compile-time polymorphism construct. You need run-time polymorphism, which can be achieved in many different ways in C++:
Inheritance +
virtualfunctions: useful when you have an interface and an open set of implementors;std::variant: useful when you have a known closed set of choices;std::any: useful when you want to store any arbitrary object without any restrictionMore:
std::function, dyno, ...
add a comment |
Templates are purely a compile-time polymorphism construct. You need run-time polymorphism, which can be achieved in many different ways in C++:
Inheritance +
virtualfunctions: useful when you have an interface and an open set of implementors;std::variant: useful when you have a known closed set of choices;std::any: useful when you want to store any arbitrary object without any restrictionMore:
std::function, dyno, ...
add a comment |
Templates are purely a compile-time polymorphism construct. You need run-time polymorphism, which can be achieved in many different ways in C++:
Inheritance +
virtualfunctions: useful when you have an interface and an open set of implementors;std::variant: useful when you have a known closed set of choices;std::any: useful when you want to store any arbitrary object without any restrictionMore:
std::function, dyno, ...
Templates are purely a compile-time polymorphism construct. You need run-time polymorphism, which can be achieved in many different ways in C++:
Inheritance +
virtualfunctions: useful when you have an interface and an open set of implementors;std::variant: useful when you have a known closed set of choices;std::any: useful when you want to store any arbitrary object without any restrictionMore:
std::function, dyno, ...
answered Nov 20 at 14:19
Vittorio Romeo
56.9k17152292
56.9k17152292
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%2f53394928%2fhow-can-i-make-a-class-agnostic-of-its-members-type%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
4
You'll need some kind of type erasure then. If C++17 is an option, you might want to try
std::any.– lubgr
Nov 20 at 14:16
1
You're out of luck. Templates are a compile-time feature. Polymorphism might be a better tool for your job.
– DeiDei
Nov 20 at 14:16
Thanks @lubgr, C++14 unfortunately. However you gave me a keyword to read about.
– lulijeta
Nov 20 at 14:48