Is this template possible?

Discussion in 'C++' started by Alex Buell, Jun 1, 2006.

  1. Alex Buell

    Alex Buell Guest

    Is there anyway I can do something like this? This won't compile. Any
    ideas.

    #include <iostream>

    template <typename T>
    class sample
    {
    public:
    sample(T n) { std::cout << sizeof(n) << "\n"; }
    ~sample();
    };

    int main(int argc, char *argv[])
    {
    unsigned char n = 0x55;

    sample s(n);
    return 0;
    }

    --
    http://www.munted.org.uk

    Take a nap, it saves lives.
     
    Alex Buell, Jun 1, 2006
    #1
    1. Advertising

  2. Alex Buell

    Kai-Uwe Bux Guest

    Alex Buell wrote:

    > Is there anyway I can do something like this? This won't compile. Any
    > ideas.
    >
    > #include <iostream>
    >
    > template <typename T>
    > class sample
    > {
    > public:
    > sample(T n) { std::cout << sizeof(n) << "\n"; }
    > ~sample();
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > unsigned char n = 0x55;
    >
    > sample s(n);
    > return 0;
    > }


    #include <iostream>

    class sample
    {
    public:

    template < typename T >
    sample(T const & n) {
    std::cout << sizeof(T) << "\n";
    }

    };

    int main(int argc, char *argv[])
    {
    unsigned char n = 0x55;
    sample s(n);
    return 0;
    }


    But *why*?


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Jun 1, 2006
    #2
    1. Advertising

  3. Alex Buell

    Luke Meyers Guest

    Alex Buell wrote:
    > Is there anyway I can do something like this? This won't compile. Any
    > ideas.
    >
    > template <typename T>
    > class sample
    > {
    > public:
    > sample(T n) { std::cout << sizeof(n) << "\n"; }
    > ~sample();
    > };
    >
    > int main(int argc, char *argv[])
    > {
    > unsigned char n = 0x55;
    > sample s(n);
    > return 0;
    > }


    Hmm, so you want the compiler to infer the class template parameter
    from the constructor? Seems you can't, and I guess it's because the
    compiler must know which class template to instantiate before it can
    look up the constructor. Yeah, I'm pretty sure that's it. But you can
    templatize the constructor itself, as already mentioned.

    Luke
     
    Luke Meyers, Jun 1, 2006
    #3
  4. Alex Buell

    Ian Collins Guest

    Alex Buell wrote:
    > Is there anyway I can do something like this? This won't compile. Any
    > ideas.
    >
    > #include <iostream>
    >
    > template <typename T>
    > class sample
    > {
    > public:
    > sample(T n) { std::cout << sizeof(n) << "\n"; }
    > ~sample();
    > };
    >

    not very practical, but you can use

    template <typename T>
    sample<T> maker( const T t ) { return sample<T>( t ); }

    > int main(int argc, char *argv[])
    > {
    > unsigned char n = 0x55;
    >
    > sample s(n);

    maker(n);
    > return 0;
    > }
    >



    --
    Ian Collins.
     
    Ian Collins, Jun 1, 2006
    #4
  5. Alex Buell

    Luke Meyers Guest

    Luke Meyers wrote:
    > Alex Buell wrote:
    > > Is there anyway I can do something like this? This won't compile. Any
    > > ideas.
    > >
    > > template <typename T>
    > > class sample
    > > {
    > > public:
    > > sample(T n) { std::cout << sizeof(n) << "\n"; }
    > > ~sample();
    > > };
    > >
    > > int main(int argc, char *argv[])
    > > {
    > > unsigned char n = 0x55;
    > > sample s(n);
    > > return 0;
    > > }

    >
    > Hmm, so you want the compiler to infer the class template parameter
    > from the constructor? Seems you can't, and I guess it's because the
    > compiler must know which class template to instantiate before it can
    > look up the constructor. Yeah, I'm pretty sure that's it. But you can
    > templatize the constructor itself, as already mentioned.


    Oh, just thought of another option:

    // free factory function
    template <class T>
    sample<T> createSample(T const& t);

    Luke
     
    Luke Meyers, Jun 1, 2006
    #5
  6. Alex Buell

    Alex Buell Guest

    On Thu, 01 Jun 2006 05:28:49 -0400, I waved a wand and this message
    magically appeared from Kai-Uwe Bux:

    > class sample
    > {
    > public:
    >
    > template < typename T >
    > sample(T const & n) {
    > std::cout << sizeof(T) << "\n";
    > }
    >
    > };


    Ah, brilliant thanks.
    --
    http://www.munted.org.uk

    Take a nap, it saves lives.
     
    Alex Buell, Jun 1, 2006
    #6
  7. Alex Buell

    Rolf Magnus Guest

    Ian Collins wrote:

    > Alex Buell wrote:
    >> Is there anyway I can do something like this? This won't compile. Any
    >> ideas.
    >>
    >> #include <iostream>
    >>
    >> template <typename T>
    >> class sample
    >> {
    >> public:
    >> sample(T n) { std::cout << sizeof(n) << "\n"; }
    >> ~sample();
    >> };
    >>

    > not very practical, but you can use
    >
    > template <typename T>
    > sample<T> maker( const T t ) { return sample<T>( t ); }


    Why not practical? The C++ standard library does that, too. Think of
    std::make_pair.

    >> int main(int argc, char *argv[])
    >> {
    >> unsigned char n = 0x55;
    >>
    >> sample s(n);

    > maker(n);
    >> return 0;
    >> }
    >>

    >
    >
     
    Rolf Magnus, Jun 1, 2006
    #7
  8. Alex Buell

    Ian Collins Guest

    Rolf Magnus wrote:
    > Ian Collins wrote:


    >>
    >>not very practical, but you can use
    >>
    >>template <typename T>
    >>sample<T> maker( const T t ) { return sample<T>( t ); }

    >
    >
    > Why not practical? The C++ standard library does that, too. Think of
    > std::make_pair.
    >

    I'd overlooked return value optimisations, so I guess it is practical,
    as long as you don't use it as a syntactic crutch for frequently
    building complex objects.

    This example and std::make_pair both create simple objects.

    --
    Ian Collins.
     
    Ian Collins, Jun 1, 2006
    #8
  9. Alex Buell

    Salt_Peter Guest

    Alex Buell wrote:
    > Is there anyway I can do something like this? This won't compile. Any
    > ideas.
    >
    > #include <iostream>
    >
    > template <typename T>
    > class sample
    > {
    > public:
    > sample(T n) { std::cout << sizeof(n) << "\n"; }
    > ~sample();


    Your destructor is declared but not defined.

    > };
    >
    > int main(int argc, char *argv[])
    > {
    > unsigned char n = 0x55;
    >
    > sample s(n);


    try...
    sample<unsigned char> s(n);

    > return 0;
    > }
    >


    This works:

    #include <iostream>
    #include <ostream>

    template< typename T >
    class Sample
    {
    T t;
    public:
    Sample(T n) : t(n) { }
    ~Sample() { }
    T get() const { return t; }
    };

    int main()
    {
    typedef unsigned char UChar;
    UChar uc = 0x137;

    Sample< UChar > sample(uc);
    std::cout << sample.get() << std::endl;

    return 0;
    }

    /*
    7
    */
     
    Salt_Peter, Jun 1, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Theis
    Replies:
    2
    Views:
    487
    Chris Theis
    Jul 24, 2003
  2. tom_usenet
    Replies:
    0
    Views:
    552
    tom_usenet
    Jul 24, 2003
  3. Replies:
    7
    Views:
    578
  4. Replies:
    1
    Views:
    2,130
    Gianni Mariani
    Jun 8, 2007
  5. Peng Yu
    Replies:
    3
    Views:
    793
    Thomas J. Gritzan
    Oct 26, 2008
Loading...

Share This Page