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?










share|improve this question



















  • 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














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?










share|improve this question



















  • 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












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?










share|improve this question















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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 10 at 14:13









melpomene

55.8k54387




55.8k54387










asked Nov 10 at 14:01









John Smith

4721519




4721519







  • 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




    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












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;






share|improve this answer




















    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',
    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
    );



    );













     

    draft saved


    draft discarded


















    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;






    share|improve this answer
























      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;






      share|improve this answer






















        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;






        share|improve this answer












        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;







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 10 at 14:09









        aschepler

        51k574126




        51k574126



























             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            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





















































            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







            這個網誌中的熱門文章

            How to read a connectionString WITH PROVIDER in .NET Core?

            Node.js Script on GitHub Pages or Amazon S3

            Museum of Modern and Contemporary Art of Trento and Rovereto