Is there a way to define a template member in a non-template class?
Say I have a class template named Compute
, and another class named Function_A
with a member function template:
template <typename T> void Evaluate(T parameter)
I am constrained to use the class Function_A
as it is. I already know that T
can only be one of two types type_1
and type_2
.
Is there a way to have something similar to Compute<T> C
as a member variable of Function_A
instead of defining a local Compute<T>
object inside Evaluate(...)
? I know that this is against the philosophy of using templates, hence it is likely not possible, but can ideally be done in that case instead?
I tried to have two members Compute<type_1> C1
and Compute<type_2> C2
in Function_A
, and then use them under an if (typeid(T) == typeid(type_1))
but it's a pretty hideous, and against the philosophy of using templates as well.
Just to illustrate what I mean:
template <class T>
class Compute
{
public:
T Function_B(T parameter)
{
return f.eval(parameter);
}
private:
SomeClass<T> f;
}
And a class:
class Function_A
{
public:
template <typename T> T Evaluate(T parameter)
{
Compute<T> C; //this is very expensive!
T value = C.Function_B(parameter);
return value;
}
private:
double SomeParameter;
//Compute<T> C; //conceptually what I want
}
c++ class templates
New contributor
add a comment |
Say I have a class template named Compute
, and another class named Function_A
with a member function template:
template <typename T> void Evaluate(T parameter)
I am constrained to use the class Function_A
as it is. I already know that T
can only be one of two types type_1
and type_2
.
Is there a way to have something similar to Compute<T> C
as a member variable of Function_A
instead of defining a local Compute<T>
object inside Evaluate(...)
? I know that this is against the philosophy of using templates, hence it is likely not possible, but can ideally be done in that case instead?
I tried to have two members Compute<type_1> C1
and Compute<type_2> C2
in Function_A
, and then use them under an if (typeid(T) == typeid(type_1))
but it's a pretty hideous, and against the philosophy of using templates as well.
Just to illustrate what I mean:
template <class T>
class Compute
{
public:
T Function_B(T parameter)
{
return f.eval(parameter);
}
private:
SomeClass<T> f;
}
And a class:
class Function_A
{
public:
template <typename T> T Evaluate(T parameter)
{
Compute<T> C; //this is very expensive!
T value = C.Function_B(parameter);
return value;
}
private:
double SomeParameter;
//Compute<T> C; //conceptually what I want
}
c++ class templates
New contributor
add a comment |
Say I have a class template named Compute
, and another class named Function_A
with a member function template:
template <typename T> void Evaluate(T parameter)
I am constrained to use the class Function_A
as it is. I already know that T
can only be one of two types type_1
and type_2
.
Is there a way to have something similar to Compute<T> C
as a member variable of Function_A
instead of defining a local Compute<T>
object inside Evaluate(...)
? I know that this is against the philosophy of using templates, hence it is likely not possible, but can ideally be done in that case instead?
I tried to have two members Compute<type_1> C1
and Compute<type_2> C2
in Function_A
, and then use them under an if (typeid(T) == typeid(type_1))
but it's a pretty hideous, and against the philosophy of using templates as well.
Just to illustrate what I mean:
template <class T>
class Compute
{
public:
T Function_B(T parameter)
{
return f.eval(parameter);
}
private:
SomeClass<T> f;
}
And a class:
class Function_A
{
public:
template <typename T> T Evaluate(T parameter)
{
Compute<T> C; //this is very expensive!
T value = C.Function_B(parameter);
return value;
}
private:
double SomeParameter;
//Compute<T> C; //conceptually what I want
}
c++ class templates
New contributor
Say I have a class template named Compute
, and another class named Function_A
with a member function template:
template <typename T> void Evaluate(T parameter)
I am constrained to use the class Function_A
as it is. I already know that T
can only be one of two types type_1
and type_2
.
Is there a way to have something similar to Compute<T> C
as a member variable of Function_A
instead of defining a local Compute<T>
object inside Evaluate(...)
? I know that this is against the philosophy of using templates, hence it is likely not possible, but can ideally be done in that case instead?
I tried to have two members Compute<type_1> C1
and Compute<type_2> C2
in Function_A
, and then use them under an if (typeid(T) == typeid(type_1))
but it's a pretty hideous, and against the philosophy of using templates as well.
Just to illustrate what I mean:
template <class T>
class Compute
{
public:
T Function_B(T parameter)
{
return f.eval(parameter);
}
private:
SomeClass<T> f;
}
And a class:
class Function_A
{
public:
template <typename T> T Evaluate(T parameter)
{
Compute<T> C; //this is very expensive!
T value = C.Function_B(parameter);
return value;
}
private:
double SomeParameter;
//Compute<T> C; //conceptually what I want
}
c++ class templates
c++ class templates
New contributor
New contributor
edited 2 days ago
Rabah
New contributor
asked 2 days ago
RabahRabah
383
383
New contributor
New contributor
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
How about (untested):
class Function_A
{
public:
template <typename T> void Evaluate(T parameter)
{
T value = std::get<Compute<T>>(computers).Function_B(parameter);
return T(SomeParameter) * value;
}
private:
double SomeParameter;
std::tuple<Compute<type_1>, Compute<type_2>> computers;
};
Note: std::pair
would work exactly the same as std::tuple
here, if you fancy the first/second semantics it adds.
Additionally, note that T(SomeParameter)
is a C-style cast, which could be problematic if T
is not a class type. Consider T{}
or static_cast<T>()
.
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
Why usestd::tuple
overstd::pair
(the latter also has get support)? I agree thatstd::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.
– Max Langhof
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, sotuple
it was.
– Quentin
2 days ago
Oh, and using astatic_cast
would be better thanT(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.
– Max Langhof
2 days ago
add a comment |
One thing you can do is make C
static
. If you have
template <typename T> void Evaluate(T parameter)
{
static Compute<T> C; // only do this once per T now
T value = C.Function_B(parameter);
return T(SomeParameter)*value;
}
then when you call Evaluate
with type_1
you'll have one version of the function that has C<type_1>
in it that will only be constructed the first time the function is called and the same thing happens for type_2
.
1
Keep in mind that you'll have to think about shared state and thread safety with this solution. EveryEvaluate<T>
call, even from differentFunction_A
objects, will use the sameCompute<T>
object.
– Kevin
2 days ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
2 days ago
2
@user463035818 In that case eachFunction_A
object gets its ownCompute<T>
. Here there's only 1Compute<T>
(perT
) shared across allFunction_A
objects. It's not necessarily a problem, but it needs to be considered.
– Kevin
2 days ago
1
@user463035818 Although in that case you can mitigate the concerns by having differentFunction_A
for each thread. My solution forces all threads to share an object, so it is something to consider.
– NathanOliver
2 days ago
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
});
}
});
Rabah is a new contributor. Be nice, and check out our Code of Conduct.
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%2f55357639%2fis-there-a-way-to-define-a-template-member-in-a-non-template-class%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
How about (untested):
class Function_A
{
public:
template <typename T> void Evaluate(T parameter)
{
T value = std::get<Compute<T>>(computers).Function_B(parameter);
return T(SomeParameter) * value;
}
private:
double SomeParameter;
std::tuple<Compute<type_1>, Compute<type_2>> computers;
};
Note: std::pair
would work exactly the same as std::tuple
here, if you fancy the first/second semantics it adds.
Additionally, note that T(SomeParameter)
is a C-style cast, which could be problematic if T
is not a class type. Consider T{}
or static_cast<T>()
.
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
Why usestd::tuple
overstd::pair
(the latter also has get support)? I agree thatstd::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.
– Max Langhof
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, sotuple
it was.
– Quentin
2 days ago
Oh, and using astatic_cast
would be better thanT(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.
– Max Langhof
2 days ago
add a comment |
How about (untested):
class Function_A
{
public:
template <typename T> void Evaluate(T parameter)
{
T value = std::get<Compute<T>>(computers).Function_B(parameter);
return T(SomeParameter) * value;
}
private:
double SomeParameter;
std::tuple<Compute<type_1>, Compute<type_2>> computers;
};
Note: std::pair
would work exactly the same as std::tuple
here, if you fancy the first/second semantics it adds.
Additionally, note that T(SomeParameter)
is a C-style cast, which could be problematic if T
is not a class type. Consider T{}
or static_cast<T>()
.
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
Why usestd::tuple
overstd::pair
(the latter also has get support)? I agree thatstd::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.
– Max Langhof
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, sotuple
it was.
– Quentin
2 days ago
Oh, and using astatic_cast
would be better thanT(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.
– Max Langhof
2 days ago
add a comment |
How about (untested):
class Function_A
{
public:
template <typename T> void Evaluate(T parameter)
{
T value = std::get<Compute<T>>(computers).Function_B(parameter);
return T(SomeParameter) * value;
}
private:
double SomeParameter;
std::tuple<Compute<type_1>, Compute<type_2>> computers;
};
Note: std::pair
would work exactly the same as std::tuple
here, if you fancy the first/second semantics it adds.
Additionally, note that T(SomeParameter)
is a C-style cast, which could be problematic if T
is not a class type. Consider T{}
or static_cast<T>()
.
How about (untested):
class Function_A
{
public:
template <typename T> void Evaluate(T parameter)
{
T value = std::get<Compute<T>>(computers).Function_B(parameter);
return T(SomeParameter) * value;
}
private:
double SomeParameter;
std::tuple<Compute<type_1>, Compute<type_2>> computers;
};
Note: std::pair
would work exactly the same as std::tuple
here, if you fancy the first/second semantics it adds.
Additionally, note that T(SomeParameter)
is a C-style cast, which could be problematic if T
is not a class type. Consider T{}
or static_cast<T>()
.
edited 2 days ago
answered 2 days ago
QuentinQuentin
46.9k592148
46.9k592148
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
Why usestd::tuple
overstd::pair
(the latter also has get support)? I agree thatstd::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.
– Max Langhof
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, sotuple
it was.
– Quentin
2 days ago
Oh, and using astatic_cast
would be better thanT(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.
– Max Langhof
2 days ago
add a comment |
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
Why usestd::tuple
overstd::pair
(the latter also has get support)? I agree thatstd::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.
– Max Langhof
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, sotuple
it was.
– Quentin
2 days ago
Oh, and using astatic_cast
would be better thanT(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.
– Max Langhof
2 days ago
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
2 days ago
4
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
2 days ago
Why use
std::tuple
over std::pair
(the latter also has get support)? I agree that std::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.– Max Langhof
2 days ago
Why use
std::tuple
over std::pair
(the latter also has get support)? I agree that std::tuple
it fits the design in principle (nothing about this is specific to having exactly two types) but I would find it worth some discussion.– Max Langhof
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, so
tuple
it was.– Quentin
2 days ago
@MaxLanghof well, what you said. There's no inherent "first" or "second" in there as far as the question goes, so
tuple
it was.– Quentin
2 days ago
Oh, and using a
static_cast
would be better than T(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.– Max Langhof
2 days ago
Oh, and using a
static_cast
would be better than T(SomeParameter)
. I was stuck trying to figure out what pointer you are dereferencing for a moment.– Max Langhof
2 days ago
add a comment |
One thing you can do is make C
static
. If you have
template <typename T> void Evaluate(T parameter)
{
static Compute<T> C; // only do this once per T now
T value = C.Function_B(parameter);
return T(SomeParameter)*value;
}
then when you call Evaluate
with type_1
you'll have one version of the function that has C<type_1>
in it that will only be constructed the first time the function is called and the same thing happens for type_2
.
1
Keep in mind that you'll have to think about shared state and thread safety with this solution. EveryEvaluate<T>
call, even from differentFunction_A
objects, will use the sameCompute<T>
object.
– Kevin
2 days ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
2 days ago
2
@user463035818 In that case eachFunction_A
object gets its ownCompute<T>
. Here there's only 1Compute<T>
(perT
) shared across allFunction_A
objects. It's not necessarily a problem, but it needs to be considered.
– Kevin
2 days ago
1
@user463035818 Although in that case you can mitigate the concerns by having differentFunction_A
for each thread. My solution forces all threads to share an object, so it is something to consider.
– NathanOliver
2 days ago
add a comment |
One thing you can do is make C
static
. If you have
template <typename T> void Evaluate(T parameter)
{
static Compute<T> C; // only do this once per T now
T value = C.Function_B(parameter);
return T(SomeParameter)*value;
}
then when you call Evaluate
with type_1
you'll have one version of the function that has C<type_1>
in it that will only be constructed the first time the function is called and the same thing happens for type_2
.
1
Keep in mind that you'll have to think about shared state and thread safety with this solution. EveryEvaluate<T>
call, even from differentFunction_A
objects, will use the sameCompute<T>
object.
– Kevin
2 days ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
2 days ago
2
@user463035818 In that case eachFunction_A
object gets its ownCompute<T>
. Here there's only 1Compute<T>
(perT
) shared across allFunction_A
objects. It's not necessarily a problem, but it needs to be considered.
– Kevin
2 days ago
1
@user463035818 Although in that case you can mitigate the concerns by having differentFunction_A
for each thread. My solution forces all threads to share an object, so it is something to consider.
– NathanOliver
2 days ago
add a comment |
One thing you can do is make C
static
. If you have
template <typename T> void Evaluate(T parameter)
{
static Compute<T> C; // only do this once per T now
T value = C.Function_B(parameter);
return T(SomeParameter)*value;
}
then when you call Evaluate
with type_1
you'll have one version of the function that has C<type_1>
in it that will only be constructed the first time the function is called and the same thing happens for type_2
.
One thing you can do is make C
static
. If you have
template <typename T> void Evaluate(T parameter)
{
static Compute<T> C; // only do this once per T now
T value = C.Function_B(parameter);
return T(SomeParameter)*value;
}
then when you call Evaluate
with type_1
you'll have one version of the function that has C<type_1>
in it that will only be constructed the first time the function is called and the same thing happens for type_2
.
answered 2 days ago
NathanOliverNathanOliver
97.1k16137213
97.1k16137213
1
Keep in mind that you'll have to think about shared state and thread safety with this solution. EveryEvaluate<T>
call, even from differentFunction_A
objects, will use the sameCompute<T>
object.
– Kevin
2 days ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
2 days ago
2
@user463035818 In that case eachFunction_A
object gets its ownCompute<T>
. Here there's only 1Compute<T>
(perT
) shared across allFunction_A
objects. It's not necessarily a problem, but it needs to be considered.
– Kevin
2 days ago
1
@user463035818 Although in that case you can mitigate the concerns by having differentFunction_A
for each thread. My solution forces all threads to share an object, so it is something to consider.
– NathanOliver
2 days ago
add a comment |
1
Keep in mind that you'll have to think about shared state and thread safety with this solution. EveryEvaluate<T>
call, even from differentFunction_A
objects, will use the sameCompute<T>
object.
– Kevin
2 days ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
2 days ago
2
@user463035818 In that case eachFunction_A
object gets its ownCompute<T>
. Here there's only 1Compute<T>
(perT
) shared across allFunction_A
objects. It's not necessarily a problem, but it needs to be considered.
– Kevin
2 days ago
1
@user463035818 Although in that case you can mitigate the concerns by having differentFunction_A
for each thread. My solution forces all threads to share an object, so it is something to consider.
– NathanOliver
2 days ago
1
1
Keep in mind that you'll have to think about shared state and thread safety with this solution. Every
Evaluate<T>
call, even from different Function_A
objects, will use the same Compute<T>
object.– Kevin
2 days ago
Keep in mind that you'll have to think about shared state and thread safety with this solution. Every
Evaluate<T>
call, even from different Function_A
objects, will use the same Compute<T>
object.– Kevin
2 days ago
@Kevin same is true on a per-object-level for having a
Compute<T>
as member which is what OP intially wanted– user463035818
2 days ago
@Kevin same is true on a per-object-level for having a
Compute<T>
as member which is what OP intially wanted– user463035818
2 days ago
2
2
@user463035818 In that case each
Function_A
object gets its own Compute<T>
. Here there's only 1 Compute<T>
(per T
) shared across all Function_A
objects. It's not necessarily a problem, but it needs to be considered.– Kevin
2 days ago
@user463035818 In that case each
Function_A
object gets its own Compute<T>
. Here there's only 1 Compute<T>
(per T
) shared across all Function_A
objects. It's not necessarily a problem, but it needs to be considered.– Kevin
2 days ago
1
1
@user463035818 Although in that case you can mitigate the concerns by having different
Function_A
for each thread. My solution forces all threads to share an object, so it is something to consider.– NathanOliver
2 days ago
@user463035818 Although in that case you can mitigate the concerns by having different
Function_A
for each thread. My solution forces all threads to share an object, so it is something to consider.– NathanOliver
2 days ago
add a comment |
Rabah is a new contributor. Be nice, and check out our Code of Conduct.
Rabah is a new contributor. Be nice, and check out our Code of Conduct.
Rabah is a new contributor. Be nice, and check out our Code of Conduct.
Rabah is a new contributor. Be nice, and check out our Code of Conduct.
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%2f55357639%2fis-there-a-way-to-define-a-template-member-in-a-non-template-class%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