using a type alias when splitting template class into header and implementation file
up vote
1
down vote
favorite
I have a templated class which is split into a .hpp
file and a .ipp
which has quite a long type in it. While refactoring I wanted to write a type alias for that type so the code could be a lot more readable. But no matter what I do I cannot get the type alias to be recognized in the .ipp
file.
Here is a simple example of what I am trying to do:
container.hpp:
template <class T>
class container {
public:
using TypeAlias = T;
container(const TypeAlias& a);
const TypeAlias& getA() const;
private:
TypeAlias a;
};
#include "container.ipp"
container.ipp:
template <class T>
container<T>::container(const TypeAlias& a) : a(a)
{
}
template <class T>
const TypeAlias& container<T>::getA() const
{
return this->a;
}
When compiling this the following error occurs:
./container.ipp:8:7: error: unknown type name 'TypeAlias'
const TypeAlias& container<T>::getA() const
Obviously in this case it doesn't make much sense to introduce the TypeAlias
but in my actual program it could make a huge difference. Is there anything I can do to make the TypeAlias available in the .ipp
file?
c++ templates typedef using
add a comment |
up vote
1
down vote
favorite
I have a templated class which is split into a .hpp
file and a .ipp
which has quite a long type in it. While refactoring I wanted to write a type alias for that type so the code could be a lot more readable. But no matter what I do I cannot get the type alias to be recognized in the .ipp
file.
Here is a simple example of what I am trying to do:
container.hpp:
template <class T>
class container {
public:
using TypeAlias = T;
container(const TypeAlias& a);
const TypeAlias& getA() const;
private:
TypeAlias a;
};
#include "container.ipp"
container.ipp:
template <class T>
container<T>::container(const TypeAlias& a) : a(a)
{
}
template <class T>
const TypeAlias& container<T>::getA() const
{
return this->a;
}
When compiling this the following error occurs:
./container.ipp:8:7: error: unknown type name 'TypeAlias'
const TypeAlias& container<T>::getA() const
Obviously in this case it doesn't make much sense to introduce the TypeAlias
but in my actual program it could make a huge difference. Is there anything I can do to make the TypeAlias available in the .ipp
file?
c++ templates typedef using
2
I assume the#include "container.ipp"
is actually at the end of container.hpp, not at the beginning of container.ipp.
– aschepler
Nov 10 at 14:10
@aschepler Yes I copied it wrong.
– John Smith
Nov 10 at 14:13
add a comment |
up vote
1
down vote
favorite
up vote
1
down vote
favorite
I have a templated class which is split into a .hpp
file and a .ipp
which has quite a long type in it. While refactoring I wanted to write a type alias for that type so the code could be a lot more readable. But no matter what I do I cannot get the type alias to be recognized in the .ipp
file.
Here is a simple example of what I am trying to do:
container.hpp:
template <class T>
class container {
public:
using TypeAlias = T;
container(const TypeAlias& a);
const TypeAlias& getA() const;
private:
TypeAlias a;
};
#include "container.ipp"
container.ipp:
template <class T>
container<T>::container(const TypeAlias& a) : a(a)
{
}
template <class T>
const TypeAlias& container<T>::getA() const
{
return this->a;
}
When compiling this the following error occurs:
./container.ipp:8:7: error: unknown type name 'TypeAlias'
const TypeAlias& container<T>::getA() const
Obviously in this case it doesn't make much sense to introduce the TypeAlias
but in my actual program it could make a huge difference. Is there anything I can do to make the TypeAlias available in the .ipp
file?
c++ templates typedef using
I have a templated class which is split into a .hpp
file and a .ipp
which has quite a long type in it. While refactoring I wanted to write a type alias for that type so the code could be a lot more readable. But no matter what I do I cannot get the type alias to be recognized in the .ipp
file.
Here is a simple example of what I am trying to do:
container.hpp:
template <class T>
class container {
public:
using TypeAlias = T;
container(const TypeAlias& a);
const TypeAlias& getA() const;
private:
TypeAlias a;
};
#include "container.ipp"
container.ipp:
template <class T>
container<T>::container(const TypeAlias& a) : a(a)
{
}
template <class T>
const TypeAlias& container<T>::getA() const
{
return this->a;
}
When compiling this the following error occurs:
./container.ipp:8:7: error: unknown type name 'TypeAlias'
const TypeAlias& container<T>::getA() const
Obviously in this case it doesn't make much sense to introduce the TypeAlias
but in my actual program it could make a huge difference. Is there anything I can do to make the TypeAlias available in the .ipp
file?
c++ templates typedef using
c++ templates typedef using
edited Nov 10 at 14:13
melpomene
58.1k54489
58.1k54489
asked Nov 10 at 14:01
John Smith
411620
411620
2
I assume the#include "container.ipp"
is actually at the end of container.hpp, not at the beginning of container.ipp.
– aschepler
Nov 10 at 14:10
@aschepler Yes I copied it wrong.
– John Smith
Nov 10 at 14:13
add a comment |
2
I assume the#include "container.ipp"
is actually at the end of container.hpp, not at the beginning of container.ipp.
– aschepler
Nov 10 at 14:10
@aschepler Yes I copied it wrong.
– John Smith
Nov 10 at 14:13
2
2
I assume the
#include "container.ipp"
is actually at the end of container.hpp, not at the beginning of container.ipp.– aschepler
Nov 10 at 14:10
I assume the
#include "container.ipp"
is actually at the end of container.hpp, not at the beginning of container.ipp.– aschepler
Nov 10 at 14:10
@aschepler Yes I copied it wrong.
– John Smith
Nov 10 at 14:13
@aschepler Yes I copied it wrong.
– John Smith
Nov 10 at 14:13
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
When you define a class member like container<T>::getA
, things after the name of the member (getA
here) are looked up in the scope of the class, but things before it are not. Essentially, if the compiler tries to understand things in order, when the declaration begins with const TypeAlias&
, it doesn't yet know that it should look inside container<T>
to figure out what TypeAlias
could mean.
So using normal function syntax, you would need to specify that TypeAlias
is a member type:
template <class T>
const typename container<T>::TypeAlias& container<T>::getA() const
{
return this->a;
}
But this is one advantage of the "trailing return type" syntax (valid in C++11 and later): Just by changing the order of things, it lets you use members of the class within the return type more simply:
template <class T>
auto container<T>::getA() const -> const TypeAlias&
{
return this->a;
}
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%2f53239721%2fusing-a-type-alias-when-splitting-template-class-into-header-and-implementation%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
When you define a class member like container<T>::getA
, things after the name of the member (getA
here) are looked up in the scope of the class, but things before it are not. Essentially, if the compiler tries to understand things in order, when the declaration begins with const TypeAlias&
, it doesn't yet know that it should look inside container<T>
to figure out what TypeAlias
could mean.
So using normal function syntax, you would need to specify that TypeAlias
is a member type:
template <class T>
const typename container<T>::TypeAlias& container<T>::getA() const
{
return this->a;
}
But this is one advantage of the "trailing return type" syntax (valid in C++11 and later): Just by changing the order of things, it lets you use members of the class within the return type more simply:
template <class T>
auto container<T>::getA() const -> const TypeAlias&
{
return this->a;
}
add a comment |
up vote
2
down vote
accepted
When you define a class member like container<T>::getA
, things after the name of the member (getA
here) are looked up in the scope of the class, but things before it are not. Essentially, if the compiler tries to understand things in order, when the declaration begins with const TypeAlias&
, it doesn't yet know that it should look inside container<T>
to figure out what TypeAlias
could mean.
So using normal function syntax, you would need to specify that TypeAlias
is a member type:
template <class T>
const typename container<T>::TypeAlias& container<T>::getA() const
{
return this->a;
}
But this is one advantage of the "trailing return type" syntax (valid in C++11 and later): Just by changing the order of things, it lets you use members of the class within the return type more simply:
template <class T>
auto container<T>::getA() const -> const TypeAlias&
{
return this->a;
}
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
When you define a class member like container<T>::getA
, things after the name of the member (getA
here) are looked up in the scope of the class, but things before it are not. Essentially, if the compiler tries to understand things in order, when the declaration begins with const TypeAlias&
, it doesn't yet know that it should look inside container<T>
to figure out what TypeAlias
could mean.
So using normal function syntax, you would need to specify that TypeAlias
is a member type:
template <class T>
const typename container<T>::TypeAlias& container<T>::getA() const
{
return this->a;
}
But this is one advantage of the "trailing return type" syntax (valid in C++11 and later): Just by changing the order of things, it lets you use members of the class within the return type more simply:
template <class T>
auto container<T>::getA() const -> const TypeAlias&
{
return this->a;
}
When you define a class member like container<T>::getA
, things after the name of the member (getA
here) are looked up in the scope of the class, but things before it are not. Essentially, if the compiler tries to understand things in order, when the declaration begins with const TypeAlias&
, it doesn't yet know that it should look inside container<T>
to figure out what TypeAlias
could mean.
So using normal function syntax, you would need to specify that TypeAlias
is a member type:
template <class T>
const typename container<T>::TypeAlias& container<T>::getA() const
{
return this->a;
}
But this is one advantage of the "trailing return type" syntax (valid in C++11 and later): Just by changing the order of things, it lets you use members of the class within the return type more simply:
template <class T>
auto container<T>::getA() const -> const TypeAlias&
{
return this->a;
}
answered Nov 10 at 14:09
aschepler
51.4k574126
51.4k574126
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%2f53239721%2fusing-a-type-alias-when-splitting-template-class-into-header-and-implementation%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
2
I assume the
#include "container.ipp"
is actually at the end of container.hpp, not at the beginning of container.ipp.– aschepler
Nov 10 at 14:10
@aschepler Yes I copied it wrong.
– John Smith
Nov 10 at 14:13