Thread: Separating declaration and definition of constructor to templated class .

  1. #1
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657

    Separating declaration and definition of constructor to templated class .

    I've a class which takes two integers as template arguments.

    When I define the constructor inside the class declaration, it works fine.

    But whenever I put it away, the compiler starts spewing strange errors...like "expected more arguments" and so on......

    Code:
    template<int foo, int bar>
    class X
    {
        public:
        X(){/*body*/}; //works as expected. 
    };
    How do I write the constructor in a .cpp file , away from the header file ?
    Last edited by manasij7479; 07-15-2011 at 08:34 AM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    This would seem to be what you want:
    Code:
    template<int foo, int bar>
    class X
    {
        public:
        X();
        private:
        int size;
    };
    
    template<int foo, int bar>
    X<foo, bar>::X() {
        size = foo * bar;
    }
    
    int main() {
        X<3,5> object;
        return 0;
    }
    You have to make sure you declare the constructor as a template object too.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It should be noted, however, that the class's implementation should not be placed in a .cpp file. It must be in the header file with the definition. This applies only to templates, just so there is no confusion.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by Elysia View Post
    It should be noted, however, that the class's implementation should not be placed in a .cpp file. It must be in the header file with the definition. This applies only to templates, just so there is no confusion.
    Why is that ?
    I've been repeatedly told that it is a good practice to put the implementations in .cpp files .
    Why should it be any different when templates come into the scenario ?

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Because templates can't be compiled by themselves -- they only produce something meaningful when they are actually used (as only then will the compiler know what T, U, foo, or bar is supposed to even be).

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #7
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Quote Originally Posted by Elysia View Post
    It should be noted, however, that the class's implementation should not be placed in a .cpp file. It must be in the header file with the definition. This applies only to templates, just so there is no confusion.
    I think it's wrong to say that the implementation must be in the header file. Sure, it makes things a lot less complicated but it isn't a requirement.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by _Mike View Post
    I think it's wrong to say that the implementation must be in the header file. Sure, it makes things a lot less complicated but it isn't a requirement.
    If you care about portability, it usually is a requirement.

    1) Not all compilers have a facility to handle separation of template definitions from declarations, which has an effect of requiring "implementations in header files".

    2) Most compilers that do have such a facility disable it by default, because using it is error-prone. It is rarely as simple as just enabling a single compilation option.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    Jan 2010
    Posts
    412
    Both MSVC and g++ accept the following code without warnings or errors and without giving any command line arguments except the filenames to compile.
    I am certainly not recommending this way; Just showing that it is possible.
    If not all compilers support it then I guess I was mistaken and I apologize.

    template.h
    Code:
    template <int foo, int bar>
    class X
    {
    public:
    	X();
    	~X();
    	int GetFoo(void) const;
    	int GetBar(void) const;
    	int GetSum(void) const;
    private:
    	int _foo;
    	int _bar;
    	int _sum;
    };
    template.cpp
    Code:
    #include "template.h"
    
    template <int foo, int bar>
    X<foo,bar>::X() : _foo(foo), _bar(bar), _sum(foo+bar)
    {
    }
    
    template <int foo, int bar>
    X<foo,bar>::~X()
    {
    }
    
    template <int foo, int bar>
    int X<foo,bar>::GetFoo(void) const
    {
    	return _foo;
    }
    
    template <int foo, int bar>
    int X<foo,bar>::GetBar(void) const
    {
    	return _bar;
    }
    
    template <int foo, int bar>
    int X<foo,bar>::GetSum(void) const
    {
    	return _sum;
    }
    
    struct instantiate_templates
    {
    	// dummy member to instantiate X<1,2>'s constructor and destructor
    	X<1,2> x;
    	// call all of X<1,2>'s methods to instantiate them
    	instantiate_templates() { x.GetFoo(); x.GetBar(); x.GetSum(); }
    } unused;
    main.cpp
    Code:
    #include <iostream>
    #include "template.h"
    
    int main()
    {
    	X<1,2> x; // works because X<1,2> is instantiated in template.cpp
    /*	X<1,3> y; // does not work because X<1,3> is not instantiated */
    	std::cout << x.GetFoo() << "+" << x.GetBar() << "=" << x.GetSum() << std::endl;
    	return 0;
    }
    The downside is that you need to know in advance which template arguments/typenames you are going to use and instantiate them explicitly. And all of X's methods gets called in unused's constructor which might be undesirable. Which is what I meant by using the header approach being less complicated.

  10. #10
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    Templates and inline functions must be placed in the header file.

    My personal practice with templates is to write a header as you would with the class definition called Classname.h, and at the end #include "Classname.hpp", which has the function definitions just like the matching cpp file would for a non-template class.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  11. #11
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by King Mir View Post
    Templates and inline functions must be placed in the header file.

    My personal practice with templates is to write a header as you would with the class definition called Classname.h, and at the end #include "Classname.hpp", which has the function definitions just like the matching cpp file would for a non-template class.
    That seems more sensible than dumping everything in the header file despite being technically same.
    I'd use this way from now on...

  12. #12
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by _Mike View Post
    I think it's wrong to say that the implementation must be in the header file. Sure, it makes things a lot less complicated but it isn't a requirement.
    I didn't say "must be," I said "should be"

    Quote Originally Posted by _Mike View Post
    Both MSVC and g++ accept the following code without warnings or errors and without giving any command line arguments except the filenames to compile.
    I am certainly not recommending this way; Just showing that it is possible.
    If not all compilers support it then I guess I was mistaken and I apologize.
    There is also a syntax to explicitly instantiate template types. The syntax is similar to:
    template<> X<1, 2>;
    (I believe!)
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  13. #13
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    The explicit instantiation syntax is:

    Code:
    template class X<foo>;
    Note the lack of <> after 'template', which distinguishes this from explicit specialization.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 40
    Last Post: 06-02-2010, 10:08 AM
  2. Separating class implementation
    By Litz in forum C++ Programming
    Replies: 5
    Last Post: 03-07-2009, 05:41 AM
  3. Replies: 7
    Last Post: 05-26-2005, 10:48 AM
  4. Templated Non-Explicit Constructor
    By golfinguy4 in forum C++ Programming
    Replies: 2
    Last Post: 08-05-2003, 02:37 PM
  5. Templated function (declaration and definition)
    By Eibro in forum C++ Programming
    Replies: 2
    Last Post: 03-11-2003, 08:07 PM