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

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














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


    }
    });














    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

        51.4k574126




        51.4k574126






























            draft saved

            draft discarded




















































            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.




            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







            這個網誌中的熱門文章

            Xamarin.form Move up view when keyboard appear

            Post-Redirect-Get with Spring WebFlux and Thymeleaf

            Anylogic : not able to use stopDelay()