template argument deduction

M

ma740988

// trial.h

#ifndef TRIAL_H
#define TRIAL_H

# include <vector>
# include <complex>
# include <iostream>

template <typename scalar>
struct complex_param
{
typedef typename std::complex<scalar> complex_type;
typedef typename std::vector< complex_type > cvec_type;
typedef typename cvec_type::size_type cvec_size_type;
typedef typename cvec_type::const_iterator cvec_const_iter;
typedef typename cvec_type::iterator cvec_iter;

};
typedef complex_param<double>::complex_type complex_d;
typedef complex_param<float>::complex_type complex_f;

typedef complex_param<double>::cvec_type cvec_type_d;
typedef complex_param<float>::cvec_type cvec_type_f;


template < typename T >
void run_it ( typename complex_param<T>::cvec_type& cvec )
{
complex_param<T>::cvec_size_type const sz = cvec.size();
for ( complex_param<T>::cvec_size_type idx ( 0 ); idx < sz; ++idx )
std::cout << cvec [ idx ] << std::endl;
}

#endif

//main.cpp
int main()
{
cvec_type_d d;
d.push_back ( complex_d ( 1.0, 2. ) );

run_it <double> ( d );
// run_it ( d ); //2
}

For the item marked "//2". .NET 2005 complains

" Could not deduce template argument for T "

Why no argument deduction for T when I used cvec_type_d and complex_d ?
 
A

Alf P. Steinbach

* ma740988:
template < typename T >
void run_it ( typename complex_param<T>::cvec_type& cvec )
{
complex_param<T>::cvec_size_type const sz = cvec.size();
for ( complex_param<T>::cvec_size_type idx ( 0 ); idx < sz; ++idx )
std::cout << cvec [ idx ] << std::endl;
}

int main()
{
cvec_type_d d;
d.push_back ( complex_d ( 1.0, 2. ) );

run_it <double> ( d );
// run_it ( d ); //2
}

For the item marked "//2". .NET 2005 complains

" Could not deduce template argument for T "

Why no argument deduction for T when I used cvec_type_d and complex_d ?

The actual argument is matched against the formal argument. Here the
formal argument /depends/ on a type T. There could be thousands of
different types T that would produce a match, and it doesn't matter that
you have defined just one.
 
B

boaz_sade

The correction should be (and it works with g++ 3.4, I will never use
microsoft compiler for anything ather then visual basic) is
typedef std::complex<scalar> complex_type;
// no need for the typename
typedef std::vector< complex_type > cvec_type;
// no need for typename
typedef typename cvec_type::const_iterator cvec_const_iter;
// typename must be used
typedef typename cvec_type::iterator cvec_iter;
// typenae must be used


template < typename T >
void run_it ( typename complex_param<T>::cvec_type& cvec )
{
tyename complex_param<T>::cvec_size_type const sz = cvec.size();
// dependent name must used with typename!!
for ( typename complex_param<T>::cvec_size_type idx ( 0 ); idx < sz;
++idx ) {
// dependent name must used with typename!!
std::cout << cvec [ idx ] << std::endl;
}

}

the rest of the code should not be changed..
good luck (and steer clean of MS "compliers")
 
A

Alf P. Steinbach

* (e-mail address removed):
The correction should be (and it works with g++ 3.4, I will never use
microsoft compiler for anything ather then visual basic) is
typedef std::complex<scalar> complex_type;
// no need for the typename
typedef std::vector< complex_type > cvec_type;
// no need for typename
typedef typename cvec_type::const_iterator cvec_const_iter;
// typename must be used
typedef typename cvec_type::iterator cvec_iter;
// typenae must be used


template < typename T >
void run_it ( typename complex_param<T>::cvec_type& cvec )
{
tyename complex_param<T>::cvec_size_type const sz = cvec.size();
// dependent name must used with typename!!
for ( typename complex_param<T>::cvec_size_type idx ( 0 ); idx < sz;
++idx ) {
// dependent name must used with typename!!
std::cout << cvec [ idx ] << std::endl;
}

}

the rest of the code should not be changed..
good luck (and steer clean of MS "compliers")

Except for the bit about MS compilers that's good advice, but doesn't
address the OP's problem.

The problematic statement, commented in the original posting, doesn't
compile no matter whether you're using MS compiler or GNU compiler.

Nor should it compile.
 
M

ma740988

The correction should be (and it works with g++ 3.4, I will never use
microsoft compiler for anything ather then visual basic) is
typedef std::complex<scalar> complex_type;
// no need for the typename
typedef std::vector< complex_type > cvec_type;
// no need for typename
typedef typename cvec_type::const_iterator cvec_const_iter;
// typename must be used
typedef typename cvec_type::iterator cvec_iter;
// typenae must be used

I thought I had a handle on when/when not to use typename. Could you
elaborate on this a little? The cases where you highlight 'no need
for typename' puzzles me a little. Perhaps it's time to pull out the
books again.
 
B

Bo Persson

ma740988 said:
I thought I had a handle on when/when not to use typename. Could
you
elaborate on this a little? The cases where you highlight 'no need
for typename' puzzles me a little. Perhaps it's time to pull out
the
books again.

The compiler knows that std::complex and std::vectors are types. :)

You need to specify 'typename' for nested types of dependent names.

std::vector<int>
std::vector<int>::iterator

but

typename std::vector<T>::iterator

(assuming T is a template parameter).



Bo Persson
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,961
Messages
2,570,130
Members
46,689
Latest member
liammiller

Latest Threads

Top