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 14 hours ago
Rabah
New contributor
asked 17 hours 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
16 hours ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours 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
16 hours 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
16 hours 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
16 hours ago
|
show 1 more 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
16 hours ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
16 hours 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
16 hours 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
16 hours 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
16 hours ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours 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
16 hours 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
16 hours 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
16 hours ago
|
show 1 more 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
16 hours ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours 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
16 hours 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
16 hours 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
16 hours ago
|
show 1 more 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 16 hours ago
answered 16 hours ago
QuentinQuentin
46.9k592148
46.9k592148
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
16 hours ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours 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
16 hours 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
16 hours 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
16 hours ago
|
show 1 more comment
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
16 hours ago
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours 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
16 hours 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
16 hours 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
16 hours ago
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
16 hours ago
Tested or not, me likes the use of the standard library to solve this
– StoryTeller
16 hours ago
4
4
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours ago
@StoryTeller of course, I'm not some kind of savage :)
– Quentin
16 hours 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
16 hours 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
16 hours 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
16 hours 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
16 hours 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
16 hours 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
16 hours ago
|
show 1 more 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
16 hours ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
16 hours 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
16 hours 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
16 hours 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
16 hours ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
16 hours 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
16 hours 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
16 hours 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 16 hours ago
NathanOliverNathanOliver
96.6k16137210
96.6k16137210
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
16 hours ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
16 hours 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
16 hours 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
16 hours 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
16 hours ago
@Kevin same is true on a per-object-level for having aCompute<T>
as member which is what OP intially wanted
– user463035818
16 hours 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
16 hours 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
16 hours 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
16 hours 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
16 hours ago
@Kevin same is true on a per-object-level for having a
Compute<T>
as member which is what OP intially wanted– user463035818
16 hours ago
@Kevin same is true on a per-object-level for having a
Compute<T>
as member which is what OP intially wanted– user463035818
16 hours 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
16 hours 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
16 hours 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
16 hours 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
16 hours 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