Why won't this template function compile?

  • Permalink
  • submit to reddit
  • Email
  • Follow


Hi,

Here's the minimal program illustrating the "mystery":

#include <vector>
using namespace std;

template <typename T>
T silly_f (typename vector<T>::const_iterator begin,
           typename vector<T>::const_iterator end)
{
    return *begin;
}

int main()
{
    vector<int> values;
    silly_f (values.begin(), values.end());

    return 0;
}

With g++ 4.1.1, I get an error in the line that calls the function ---
it tells
me "no match for call to silly_f ( ..... iterator .... ,  .....
iterator ...) --- g++
3.3.3 also gives me the same error

(the .... refers to the expanded gibberish for vector<int>::iterator )

I know that the "better" solution is to do:

template <typename Iterator>
typename Iterator::value_type silly_f (Iterator begin, Iterator end)

(not only it is better and more elegant --- it also compiles)

But I'm puzzled and would like to find out why won't the other
version compile.

Thanks,

Carlos
--


--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply cm_news (6) 4/17/2007 5:55:07 PM

See related articles to this posting


On 4��18��, ����7ʱ55��, Carlos Moreno <cm_n...@mailinator.com> wrote:
> Hi,
>
> Here's the minimal program illustrating the "mystery":
>
> #include <vector>
> using namespace std;
>
> template <typename T>
> T silly_f (typename vector<T>::const_iterator begin,
>            typename vector<T>::const_iterator end)
> {
>     return *begin;
>
> }
>
> int main()
> {
>     vector<int> values;
>     silly_f (values.begin(), values.end());
>
>     return 0;
>
> }
I think it is because the compiler can't deduce the type for the
function. just do like below:
 int main()
 {
     vector<int> values;
     silly_f <int> (values.begin(), values.end());

     return 0;
 }



--
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply zade 4/17/2007 10:47:38 PM

> > Here's the minimal program illustrating the "mystery":
> [...]
> > template <typename T>
> > T silly_f (typename vector<T>::const_iterator begin,
> >            typename vector<T>::const_iterator end)
> [...]
> > int main()
> > {
> >     vector<int> values;
> >     silly_f (values.begin(), values.end());
>  [...]
>
>      vector<int> values;
>      silly_f <int> (values.begin(), values.end());

Still does not compile  (same error message!!) --- which makes it
even more puzzling.  I thought it would compile, and I was still
going to ask:  "but why won't the other one compile?"  That is,
my interest is not really in making it work --- there is the better
solution anyway, doing template <typename Iterator> --- but
rather in understanding why is it that the compiler won't deduce
and won't see a match, even if we deduce it for the compiler?
Anyone?

Thanks,

Carlos
--


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Carlos 4/18/2007 8:57:25 AM

On Apr 18, 12:55 am, Carlos Moreno <cm_n...@mailinator.com> wrote:
> Hi,
>
> Here's the minimal program illustrating the "mystery":
>
> #include <vector>
> using namespace std;
>
> template <typename T>
> T silly_f (typename vector<T>::const_iterator begin,
>            typename vector<T>::const_iterator end)
> {
>     return *begin;
>
> }
>
> int main()
> {
>     vector<int> values;
>     silly_f (values.begin(), values.end());
>
>     return 0;
>
> }
>
> With g++ 4.1.1, I get an error in the line that calls the function ---
> it tells
> me "no match for call to silly_f ( ..... iterator .... ,  .....
> iterator ...) --- g++

values.begin() is of type vector<int>::iterator, not of type
vector<int>::const_iterator.  Thus the compiler can't match the type
of the first argument and can't deduce the template argument.


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Martin 4/18/2007 8:57:47 AM

On 18 Apr, 15:57, Carlos Moreno <cm_n...@mailinator.com> wrote:
> > > Here's the minimal program illustrating the "mystery":
> > [...]
> > > template <typename T>
> > > T silly_f (typename vector<T>::const_iterator begin,
> > >            typename vector<T>::const_iterator end)
> > [...]
> > > int main()
> > > {
> > >     vector<int> values;
> > >     silly_f (values.begin(), values.end());
> >  [...]
>
> >      vector<int> values;
> >      silly_f <int> (values.begin(), values.end());
>
> Still does not compile  (same error message!!)

This does compile with gcc 3.4.4 and 4.1.2.

>  "but why won't the other one compile?"

Because the standard says so in 14.8.2.4/4.
    -4- The nondeduced contexts are:
        * The nested-name-specifier of a type that was
          specified using a qualified-id.
        ...
The compiler is forbidden to try and deduce the type T. But, even
if it wasn't, how could it, without the explicit knowledge of
std::vector,
tell that T=int is a match? And more, how could it tell that it's the
_only_ match?

Regards
Vladimir Marko


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Vladimir 4/18/2007 10:53:07 AM

> > template <typename T>
> > T silly_f (typename vector<T>::const_iterator begin,
> >            typename vector<T>::const_iterator end)

> values.begin() is of type vector<int>::iterator, not of type
> vector<int>::const_iterator.  Thus the compiler can't match the type
> of the first argument and can't deduce the template argument.

D'oh!  I would have sworn that I copy-n-pasted, but apparently I
didn't,
since in my code, I used iterator, and not const_iterator" ...
(sorry
about that!  I shouldn't make these types of trivial mistakes!)

Ok, now I'm going to copy-n-paste the entire file, and post the
*exact*
error message:

---  BEGIN FILE test.c++  ---
#include <vector>
using namespace std;

template <typename T>
T silly_f (typename vector<T>::iterator begin,
           typename vector<T>::iterator end)
{
    return *begin;
}

int main()
{
    vector<int> values;
    silly_f (values.begin(), values.end());

    return 0;
}
---  END FILE test.c++  ---

Compiled with:  c++ -c test.c++

test.c++: In function 'int main()':
test.c++:14: error: no matching function for call to
'silly_f(__gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int> > >, __gnu_cxx::__normal_iterator<int*,
std::vector<int, std::allocator<int> > >)'

Now, the funny thing is:  with the previous poster's suggestion
(calling it
like  silly_f<int> ( ... ) ), then it does compile  (I was on another
computer
and I copy-n-pasted from what I had posted --- so now, the error was
due
to the const_iterator vs. iterator).

So, the mystery is still on ...  (compiler bug?  I still refuse to
believe that
this may be the case --- g++ is notoriously good at template stuff;
this
one seems like a particularly trivial bug when it comes to templates,
so
it would be quite surprising)

Is it possible that it is related to the nested-type-in-a-template
issue?
The same reason why we need to "help" the compiler, using the keyword
typename so that it knows that vector<T>::iterator refers to a type?
Even if that's the case, I don't know ...  Seems like a trivial match
to
deduce...

Thanks,

Carlos
--



-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Carlos 4/18/2007 11:44:20 AM

> > >      silly_f <int> (values.begin(), values.end());
>
> > Still does not compile  (same error message!!)
>
> This does compile with gcc 3.4.4 and 4.1.2.

Silly error from my part --- see my other post in this sub-thread.

> >  "but why won't the other one compile?"
>
> Because the standard says so in 14.8.2.4/4.
>     -4- The nondeduced contexts are:
>         * The nested-name-specifier of a type that was
>           specified using a qualified-id.

Hmmm, is this really the case??  I'm probably confused about the
terminology, but the nested-name is iterator, and not T  (iterator
was qualified with the scope-resolution operator).

> The compiler is forbidden to try and deduce the type T. But, even
> if it wasn't, how could it, without the explicit knowledge of
> std::vector,
> tell that T=int is a match? And more, how could it tell that it's the
> _only_ match?

And who said that the compiler has no explicit knowledge of
std::vector??  I #included <vector>, where the compiler finds
everything that it ever may need to know about vector  (not to
mention the issue that, since vector is fully documented in the
standard, why wouldn't the compiler assume knowledge about
it? --- well, ok, this is an entirely separate discussion, so let's
say that we avoid that tangent)

The thing is, putting aside the fact that the standard says that
there is no match --- I don't see why it could not see that match
(seems obvious enough for you;  maybe it's related to the way
compilers are implemented?  An area which I'm 150% unfamiliar
with!) ...

The given type is known --- vector<int>::iterator;  an available
template has been given, and fully described/visible to the
compiler, since #include <vector> is present;  the available
template has a type member iterator;  this constitutes a match
for vector<int>::iterator  given by  vector<T>::iterator for T=int.

Why would the compiler not know, or not know that it is the
only match?

Carlos
--




-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Carlos 4/18/2007 1:46:36 PM

Carlos Moreno wrote:
::
:: And who said that the compiler has no explicit knowledge of
:: std::vector??  I #included <vector>, where the compiler finds
:: everything that it ever may need to know about vector  (not to
:: mention the issue that, since vector is fully documented in the
:: standard, why wouldn't the compiler assume knowledge about
:: it? --- well, ok, this is an entirely separate discussion, so let's
:: say that we avoid that tangent)
::
:: The thing is, putting aside the fact that the standard says that
:: there is no match --- I don't see why it could not see that match
:: (seems obvious enough for you;  maybe it's related to the way
:: compilers are implemented?  An area which I'm 150% unfamiliar
:: with!) ...
::
:: The given type is known --- vector<int>::iterator;  an available
:: template has been given, and fully described/visible to the
:: compiler, since #include <vector> is present;  the available
:: template has a type member iterator;  this constitutes a match
:: for vector<int>::iterator  given by  vector<T>::iterator for T=int.
::
:: Why would the compiler not know, or not know that it is the
:: only match?

The problem is that the compiler cannot know that vector<int>::iterator is
different from all other vector<T>::iterator, until it has tried to
instantiate std::vector for ALL possible values of T.

What if I have:

struct MySillyType
{ };

template<>
class std::vector<MySillyType>
{
     typedef std::vector<int>::iterator   iterator;
};

Now silly_f<int>() and silly_f<MySillyType>() has the same signature. 
How is
the compiler to know? It just cannot!


Bo Persson






-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Bo 4/18/2007 11:09:45 PM

Carlos Moreno schrieb:
> > > template <typename T>
> > > T silly_f (typename vector<T>::const_iterator begin,
> > >            typename vector<T>::const_iterator end)
>
> > values.begin() is of type vector<int>::iterator, not of type
> > vector<int>::const_iterator.  Thus the compiler can't match the type
> > of the first argument and can't deduce the template argument.
>
> D'oh!  I would have sworn that I copy-n-pasted, but apparently I
> didn't,
> since in my code, I used iterator, and not const_iterator" ...
> (sorry
> about that!  I shouldn't make these types of trivial mistakes!)

Note that your problem has *nothing* to do with choosing
vector<T>::iterator over vector<T>::const_iterator (that is only
relevant for your internal logic).
Vladimir Marko has given the correct answer: Your are defining
your function template in a way that all function parameters are in
a nondeduced context. In this situation 14.8.2.4/3 applies:

"[..] If a template parameter is used only in nondeduced contexts
and is not explicitly specified, template argument deduction fails."

So in your situation you *must* explicitly provide the argument
type. After doing this the code will compile with either
vector<T>::iterator or vector<T>::const_iterator, because
the vector<T>::iterator is valid and convertible to
vector<T>::const_iterator.

> Now, the funny thing is:  with the previous poster's suggestion
> (calling it
> like  silly_f<int> ( ... ) ), then it does compile  (I was on another
> computer
> and I copy-n-pasted from what I had posted --- so now, the error was
> due
> to the const_iterator vs. iterator).

As explained above in this situation explicitely specifying
the template argument type is required and not optional.

> The same reason why we need to "help" the compiler, using the keyword
> typename so that it knows that vector<T>::iterator refers to a type?
> Even if that's the case, I don't know ...  Seems like a trivial match
> to
> deduce...

It has no relation to provide a "typename" in front of a dependent
qualified-id. The reason is that it is in general impossible to deduce
the "base" (or parts of it) from a qualified-id of the actually
qualified
"leaf". Assume that std::vector<int>::iterator is int*. Given the int*
as
result, how do you unambigiously deduce the leading std::vector<int>?

Greetings from Bremen,

Daniel Kr�gler



-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply iso 4/18/2007 11:10:17 PM

Carlos Moreno wrote:
> Even if that's the case, I don't know ...  Seems like a trivial match
> to deduce...

As has already been posted, T is not deducible from the
arguments. You can read the standard for chapter and verse,
but the basic problem is that there can be an infinite
number of matches. Here's why - I can write a specialization
like this:

class a { };
template <>
class std::vector<a> {
public:
     typedef vector<int>::iterator iterator;
};

This makes vector<int>::iterator and vector<a>::iterator be
the same type, so you can see why simply having the iterator
doesn't let you go back to the type parameter.

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Hyman 4/18/2007 11:11:01 PM

Hyman Rosen wrote:
> class a { };
> template <>
> class std::vector<a> {
> public:
>     typedef vector<int>::iterator iterator;
> };

The actual legal syntax for the above would be
     #include <vector>
     class a { };
     namespace std {
         template <> class vector<a> {
         public: typedef vector<int>::iterator iterator;
         };
     }
Sorry about that.

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Hyman 4/19/2007 11:01:29 AM

> The problem is that the compiler cannot know that vector<int>::iterator is
> different from all other vector<T>::iterator, until it has tried to
> instantiate std::vector for ALL possible values of T.

Ok --- this is the key element that I was failing to see!!  (looked
like a
trivial match because I was looking just at a sub-set of the
scenario!)

Still --- and please, do not take the following as me being dense;
just
enjoying the discussion just for the sake of working the ideas:

> struct MySillyType
> { };
>
> template<>
> class std::vector<MySillyType>
> {
>      typedef std::vector<int>::iterator   iterator;
>
> };
>
> Now silly_f<int>() and silly_f<MySillyType>() has the same signature.
> How is
> the compiler to know? It just cannot!

What do you mean it can not??  We can --- and I mean, our brains do
determine in an *fully objective* and completely unambiguous and
undebatable way, if there is a match or there is ambiguity.  Why
wouldn't the compiler be able to?

I mean, the issue is:  if two instances of vector<T>::iterator are
the
same, then the call would be ambiguous --- nothing new there:  but
if the compiler only sees the one definition (by means of a *generic*
without any specialized definition) that could match, then where's
the problem?

If two iterators for two different instances of vector<T> are the
same,
the compiler should see it --- if you are in a context where the
vector<MySillyType> counts, then the definition of SillyType and
that of vector<SillyType> will have been seen.  If they have been
seen, then the compiler will (rightfully) declare ambiguity.

And if they (SillyType and vector<SillyType> have not been seen, then
the match for the call that the compiler is seeing (in the main
program)
can not be that for SillyType, nor it would matter that the compiler
did
not consider SillyType as a candidate match.

What am I missing?

(no, I'm not missing the fact that the standard simply says that the
compiler won't do it --- that part is already understood and
accepted;
my argument now goes around the rationale about why is it not
possible
for the compiler to deduce the template parameter in these types of
situations --- simply curious/puzzled, not trying to be dense)

Thanks,

Carlos
--


-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Carlos 4/19/2007 1:43:15 PM

Carlos Moreno wrote:
> We can ... if there is a match or there is ambiguity.
> Why wouldn't the compiler be able to?
> What am I missing?

You're failing to generalize from the examples given.
Perhaps this will make it more clear:

     template <typename T> struct X { typedef char (&t)[sizeof(T)]; };
     template <typename U> void f(typename X<U>::t);
     void g(X<int>::t a) { f(a); }

Can you see why the compiler cannot deduce U from f's argument?

-- 
      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply Hyman 4/19/2007 3:40:59 PM

Carlos Moreno wrote:
>> struct MySillyType
>> { };
>>
>> template<>
>> class std::vector<MySillyType>
>> {
>>      typedef std::vector<int>::iterator   iterator;
>>
>> };
>>
>> Now silly_f<int>() and silly_f<MySillyType>() has the same signature.
>> How is
>> the compiler to know? It just cannot!
> 
> What do you mean it can not??  We can --- and I mean, our brains do
> determine in an *fully objective* and completely unambiguous and
> undebatable way, if there is a match or there is ambiguity.  Why
> wouldn't the compiler be able to?

Not really, we can tell there is ambiguity only beacause the example is 
so trivial. In general, however, it is algorithmically impossible to 
decide whether there is an ambiguity or not. I spent the last few hours 
learning Boost.Mpl so I could prove it :-) --- in the following code, 
'post_checker<I, S>::type' is 'true_' if and only if 'S' is a solution 
of the Post correspondence problem 'I' or 'S' is 'true_'. Hence, the 
deduction in call to 'foo(true_())' would be ambiguous iff the problem 
'instance' had a solution.

Since it is impossible to decide whether a given Post correspondence 
problem has a solution, the compiler can say nothing about the ambiguity 
of type deduction in call to 'foo(true_())'.

#include <boost/mpl/vector.hpp>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/pair.hpp>
#include <boost/mpl/fold.hpp>
#include <boost/mpl/insert_range.hpp>
#include <boost/mpl/equal.hpp>
#include <boost/mpl/at.hpp>
using namespace boost::mpl;

template <class Instance, class Solution>
struct post_checker
{
     typedef
         typename reverse_fold<
             Solution,
             vector<>,
             insert_range<_1, begin<_1>,
                 at<typename first<Instance>::type, _2> >
         >::type left_word;

     typedef
         typename reverse_fold<
             Solution,
             vector<>,
             insert_range<_1, begin<_1>,
                 at<typename second<Instance>::type, _2> >
         >::type right_word;

     typedef typename equal<left_word, right_word>::type type;
};

template <typename Instance>
struct post_checker<Instance, true_>
{
     typedef true_ type;
};

// This is an instance of the Post correspondence problem,
// the sequences are ("aba", "bbb", "aab", "bb") and
// ("a", "aaa", "abab", "babba"). For the record,
// the instance has a solution and that is (0, 3, 2, 0)
// if we're indexing from zero. The example was taken
// from Wikipedia page on PCP.
typedef
     pair<
         vector<
             vector_c<char, 'a', 'b', 'a'>::type,
             vector_c<char, 'b', 'b', 'b'>::type,
             vector_c<char, 'a', 'a', 'b'>::type,
             vector_c<char, 'b', 'b'>::type
         >,
         vector<
             vector_c<char, 'a'>::type,
             vector_c<char, 'a', 'a', 'a'>::type,
             vector_c<char, 'a', 'b', 'a', 'b'>::type,
             vector_c<char, 'b', 'a', 'b', 'b', 'a'>::type
         >
     >
     instance;

template <typename Solution>
void foo(typename post_checker<instance, Solution>::type)
{
}

int main()
{
     // If the standard allowed the deduction,
     // would it be ambiguous in the call below?
     //
     // foo(true_());

     // Test the correctness of post_checker...
     foo<true_>(true_());
     foo<vector_c<int, 0, 3, 2, 0> >(true_());
     foo<vector_c<int, 0, 3, 2, 1> >(false_());
}

-- 
Best regards,
Martin Vejn�r


      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.moderated.    First time posters: Do this! ]

0
Reply ISO 4/26/2007 4:12:09 PM
comp.lang.c++.moderated 10632 articles. 8 followers. Post

13 Replies
144 Views

Similar Articles

[PageSpeed] 39


  • Permalink
  • submit to reddit
  • Email
  • Follow


Reply:

Similar Artilces:

compile error with Boost Function object and templated function (Intel C++ compiler)
Hi, The following bit of code compiles fine with gcc 3.3 or later, but has problems with the Intel C++ compiler version 9.1, which produces the following error message. Is this a compiler bug, or is there something wrong with the code? If the former, I'd be grateful for suggestions of a workaround, and if the latter, please tell me what I'm doing wrong. Note that the corresponding version with no templates compiles without problems. Thanks in advance. Faheem. ************************************************************************** icp...

Error compiling template function within class template
template <class T> class foo { public: template <class Tin> T bar (Tin) {return T();} }; class derived : public foo<derived> { }; Some compilers compile successfully, while another tells me that I'm using the undefined class 'derived'. Is this little chunk of code compliant with the ISO C++ standard or not? uvts_cvs@yahoo.com wrote: > template <class T> > class foo > { > public: > template <class Tin> > T bar (Tin) {return T();} > }; > > class derived : public foo<derived> > { > }; > > Some compilers ...

Error compiling template function within class template #2
template <class T> class foo { public: template <class Tin> T bar (Tin) {return T();} }; class derived : public foo<derived> { }; Is this little chunk of code ISO C++ compliant? Some compilers compile it successfully, while another tells me that 'derived' is undefined within the class template. uvts_cvs@yahoo.com wrote: > template <class T> > class foo > { > > public: > template <class Tin> > T bar (Tin) {return T();} > > }; > > class derived : public foo<derived> > { > > }; > > Is this lit...

computation at compile time i.e. compile time functions using templates
Hi, I am a bit new when it comes to C++ and I wasnt sure how to go about doing this. How does one compute values at compile which can be plugged into a static const value using a template. I remember seeing in a book I no longer have some method for doing this. For example the book gives a method for computing at compile time the value of Fibonacci sequence where the value is generated by the compiler. Unfortunately I seem to have misplaced the book. Thanks in advance, Carter. Carter wrote: > I am a bit new when it comes to C++ and I wasnt sure how to go about > doing this. How does ...

Explicit template instantiation from template function doesn't compile?
Hi, I'm trying to explicitly instantiate a template function using the following syntax: obj.template_func<type>(params); It compiles OK when used from a regular function, but it doesn't compile when used in a template function. Is there any particular reason for this, or is this a compiler bug? I'm using GCC 3.2.3 on Debian Linux. An example program follows here: //--------------------------------------------------------------- #include <iostream> using namespace std; class Test { public: template<class T> void DoIt(int i) { ...

Compiling template function
Hello I get linker error with files like these: //function.h template <typename T> void function(T*); //function.cpp template <typename T> void function(T* v) { ... } // main.cpp int main() { float v; function(v); } g++ -o main main.o function.o <-- Linker error. > //function.h > template <typename T> void function(T*); > > //function.cpp > template <typename T> void function(T* v) > { > ... > } > > // main.cpp > int main() > { > float v; > function(v); > } Move the implementation of the ...

Separate Template Definition I wrote class Data in header. The C++ Compiler compiled without errors. I decided to move all member functions into source code because they are for implementati
I wrote class Data in header. The C++ Compiler compiled without errors. I decided to move all member functions into source code because they are for implementation. I do not like that they are placed in class body. I got error message: Linking... Main.obj : error LNK2001: unresolved external symbol "public: __thiscall Data<unsigned char>::operator unsigned char(void)" (??B? $Data@E@@QAEEXZ) C:\Main.exe : fatal error LNK1120: 1 unresolved externals Could be problem with member function cast operator. All other member functions complied without any problems. // Data.h ...

function template compilation error.
Hi, I'm using the g++ compiler to compile this on SunOS 5.8. I get compilation errors when I use A* as return type but none when I used void . why is this ? regards, Aman. ----------errors ------------------- :6: syntax error before `*' :20: syntax error before `*' :20: `T' was not declared in this scope :20: template argument 1 is invalid :20: `T' was not declared in this scope :20: parse error before `)' :21: ANSI C++ forbids declaration `function' with no type ----------- Code -------------------- #include <iostream> using namespace std ; template <t...

compilation error with function template
I want to learn the use of value_type member of the standard library container. For this, I want to write a template to sum the elements in a container, say for example vector<int>.( I do not want to use accumulate algorithm in this example program just for learning purpose). I try to write 'function template' because I want this program to run for any container of objects of user-defined class types also, with appropriate operator+() defined. #include <cstdlib> #include <iostream> #include <vector> using namespace std; template <typename Container> Con...

a compiler error with template function
Hi, I have a template function that triggered some compiler error. The abridged version of the class and function is: #include<memory> using namespace std; template <class T> class Vec{ public: T* data; T* avail; T* limit; std::allocator<T> alloc; template<class In> void create (In,In); }; template<class T,class In> void Vec<T>::create(In i, In j){ data = alloc.allocate(j - i); limit = avail = std::uninitialized_copy(i,j,data); } The compiler error was: error: prototype for 'void Vec<T>::create(In, In)' does not match any...

compilation error with function template parameter
The following quesion is NOT a HOMEWORK problem. Consider the following x.cpp: #include <cstdlib> #include <iostream> using namespace std; template<class T> inline void fn(void (T::*memfnPtr)()) { return; } class Test { public: void member(); void member() const; }; inline void Test::member(void) { cout << "Test::member() called" << endl; return; } inline void Test::member(void) const { cout << "Test::member() const called" << endl; return; } int main() { fn(&Test...

compiler instantiates wrong function template??
template<class T> int dump( ){ T t; cout<<t; } main(){ dump<Foo>(); dump<Bar>(); } in my case compiler seems to only generate code for whatever function is called last, in this case dump<Bar> and so Foo is not output. if i switch order of calls, dump<Foo> is generated and Bar is not dumped. why is that? does anybody have an explanation? Compiler is VC++ 6. thanks. [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] "dima" <dbabits@hotmail.com> w...

compiling class-template member function
Hi, I am using visual studio.net and I am having problems using this bit of code when I create an instance, //////////////////////////////////////////// template<class T> class matrix : public vector<T> { public: matrix(size_t h, size_t w) : vector(h*w), width(w) {} reference operator()(int i, int j) { return (*this)[i*width+j]; } const_reference operator()(int i, int j) const { return (*this) [i*width+j]; } protected: size_t width; }; ////////////////////////////////////////////// error C2955: 'std::vector' : use of class template requires template argument...

Template function problem language or compiler bug?
Hi, I found a bit of a weirdo using Intel 4.5 compiler & I've seen similar bad stuff in VC6. I don't know if it is a language 'feature' or a bug in the compiler's template handling - the compilers are old. Basically I have a template function (as a member in a class) with void return & argument. To use the function you have to explicitly tell the compiler what type - or the compiler errors (reasonable as it can't determine the type!). The linked program then uses the first type encountered for all links to that function (i.e. _same_ address) regardless of they...

class template member function
consider the following program #include <iostream> using namespace std; class Rec { public: Rec(int arg = 10) : val(arg) { } private: int val; }; template <class T> class Test { private: T t; public: void print( ) const { cout << t << endl; } }; int main( ) { Test<Rec> r; // r.print( ); return 0; } This program compiles fine with g++ and VC++2005 Express Edition. However if I remove the comment in the line // r.print( ), I get compilation error because operator<<( ) is not defined for Rec. Why doesn't the compiler report this er...

Why won't this template function compile?
Hi, Here's the minimal program illustrating the "mystery": #include <vector> using namespace std; template <typename T> T silly_f (typename vector<T>::const_iterator begin, typename vector<T>::const_iterator end) { return *begin; } int main() { vector<int> values; silly_f (values.begin(), values.end()); return 0; } With g++ 4.1.1, I get an error in the line that calls the function --- it tells me "no match for call to silly_f ( ..... iterator .... , ..... iterator ...) --- g++ 3.3.3 also gives me the same error...

Function Template Problem With MSVS 2005 compiler
{ Multi-posted to [comp.lang.c++]. -mod } I dont know whether this is the correct group for this post as it seems to specific to the Microsoft Visual Studio 2005 C++ compiler. I have begun to construct a function template for a Gauss Seidel procedure to solve a system of linear equations. The code can be seen here: ------------------------------------------------------------------------------ // Main.cpp #include<iostream> #include<iomanip> #include<cmath> using namespace std; template<typename T, int n> void GaussSeidel(T A[][n], T x[n], T b[n], int iter = 20) { f...

Function Template Problem With MSVS 2005 compiler
I dont know whether this is the correct group for this post as it seems to specific to the Microsoft Visual Studio 2005 C++ compiler. I have begun to construct a function template for a Gauss Seidel procedure to solve a system of linear equations. The code can be ssen here: ------------------------------------------------------------------------------ // Main.cpp #include<iostream> #include<iomanip> #include<cmath> using namespace std; template<typename T, int n> void GaussSeidel(T A[][n], T x[n], T b[n], int iter = 20) { for(int i=0; i<iter; i++) { x[0] = b[0...

static function template problem on sun compiler
Hi, everyone I've got problem. I am able to compile following code without error on Compaq, Linux machine But I am not able to compile this with error on Sun with forte7 compiler: line 26: Unexpected type name: Apple Please carefully review following code And Let me know what problem is and how to solve this problem 1 class Apple 2 { 3 public: 4 static int load(); 5 }; 6 7 class Banana 8 { 9 public: 10 template<typename EL> 11 void load() 12 { 13 m_banana = EL::load(); 14 } 15 16 private: 17 int m_banana; 18 }; 19 20 class Peach 21 { 22 public: 23 static void init...

Template function with enum usage
class RockProp { public: enum Field {WELLNAMES, CELLS, SELECTEDPROPERTIES, REPORTLABELS, COMMENT, FIELDEND}; ========== ========== ========== } class WellProp { public: enum Field {WELLNAMES, CELLS, SELECTEDPROPERTIES, REPORTLABELS, COMMENT, FIELDEND}; ========== ========== ========== } ================ Template call : WellProp *pNode=new WellProp () ; convertReportLabels(pNode,nType); Function : template<typename T> bool RepMgrNodeTree::convertReportLabels(T *pNode,int nType) { if(pNode) { vector<string> ...

Function objects/templates. Why won't this compile?
I'm playing with function objects and trying to bind a function object to a member function (), taking multiple arguments (std::mem_fun only works with one). However it doesn't compile (a slew of template errors that are incomprehensible to me). I'm not sure how to generate myFunction1, given the class and an instance. Can anyone shed some light on this for me please? Thankyou. #include <boost/bind.hpp> #include <boost/function.hpp> using namespace std; class Someclass { public: template<typename T1> void operator ()(T1 t1) cons...

a compiler error in template function default argument value
Hi, all. I encounter a compiler error in gcc 3.4. Is there anyone encounter the some situation. And why ??? ///////////////////////////////////// #include <iostream> using namespace std; #define INT_ID 1 #define FLOAT_ID 2 #define CHAR_ID 3 template<int tid> struct Tid2T{}; #define TID2T_HELPER(id, type)\ template<>\ struct Tid2T<id>{\ typedef type TyT;\ }; TID2T_HELPER(INT_ID, int) TID2T_HELPER(FLOAT_ID, float) TID2T_HELPER(CHAR_ID, char) template<int tid> class TS{ public: typename Tid2T<tid>::TyT m_i; TS(typename Tid2T<tid>::TyT val...

Static variable in template function across compilation units
Hello ! I am trying to write several counters for a program depending on some types. I thus have written a template function containing a static int which is increased each time the function is called. Across the compilation units, the function should be instantiated only one for each dependent type and the static variables be shared across compilation units for each type. However under Visual C++ this is the case when compiling in debug mode but not in release mode... Could someone please tell me what should be the expected behavior ? and a workaround ? Thanks in advance, Here is a simple ...

Problem compiling template function with typename for dependent names
Hi all, I have a short question. The following program does not compile using g++4.= 6.3, =BFwhy? #include <list> template <class T> void empty (typename std::list<T>::iterator it) {} int main() { std::list<int> l; empty(l.begin()); } Am 20.11.2012 09:33, schrieb antoniogarcar@gmail.com: > > The following program does not compile using g++4.6.3, �why? > > #include <list> > > template <class T> > void empty (typename std::list<T>::iterator it) - ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...

a compiler error in template function default argument value
Hi, all. I encounter a compiler error in gcc 3.4. Is there anyone encounter the some situation. And why ??? ///////////////////////////////////// #include <iostream> using namespace std; #define INT_ID 1 #define FLOAT_ID 2 #define CHAR_ID 3 template<int tid> struct Tid2T{}; #define TID2T_HELPER(id, type)\ template<>\ struct Tid2T<id>{\ typedef type TyT;\ }; TID2T_HELPER(INT_ID, int) TID2T_HELPER(FLOAT_ID, float) TID2T_HELPER(CHAR_ID, char) template<int tid> class TS{ public: typename Tid2T<tid>::TyT m_i; TS(typename Tid2T<tid>::TyT val):...