justik
justik

Reputation: 4255

Invalid explicit argument

The following code compiles correctly on g++ (Debian) with 0 warnings:

#include <list>

template <typename T>
struct A
{
T a;
typedef T value_type;
};


template <typename T>
struct B
{
 typedef std::list < A <T> > Type;
};


template <typename Data>
void test ( Data d, typename Data::value_type::value_type b ) { }


int main(int argc, char* argv[])
{
B <double> ::Type b;
double c = 0.0;
test <typename B <double>::Type > (b, c);
return 0;
}

However, after VS 2010 compiler used, the following error occured:

Error   1   error C2770: invalid explicit template
argument(s) for 'void test(Data,Data::value_type::{ctor})

Why is the explicit argument not correct?

Updated question

I am not sure if your advice was understood correctly. You mentioned something like this? However, this construction does not make sense to me.

template <typename Data>
void test ( Data d, typename identity <typename    Data::value_type>::type::value_type  b) { }

Upvotes: 0

Views: 2651

Answers (2)

daz azemoon
daz azemoon

Reputation: 1

I know it's an old post but just in case it helps anyone (note the addition of the template keyword in the declaration of the second argument of test():

#include <list>

template <typename T>
struct A
{
T a;
typedef T value_type;
};


template <typename T>
struct B
{
 typedef std::list < A <T> > Type;
};


template <typename Data>
void test ( Data d, typename Data::value_type::template value_type b ) { }


int main(int argc, char* argv[])
{
B <double> ::Type b;
double c = 0.0;
test <typename B <double>::Type > (b, c);
return 0;
}

This should compile with VS 2010

Upvotes: 0

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 506905

The problem here is that your compiler implements a rule that was present in only a pre-C++11 draft and was added there to make inheriting constructors work when the base class is only known via a typedef. Saying using TypedefName::TypedefName; then makes the using declaration refer to the base class constructors (in your case the parameter type is made incorrectly refering to the constructors of A <double>).

The problem was that this handling was active even outside of using declarations. After a defect report noted that, the handling was reduced to only using declarations. So your code is correct and the compiler is wrong.

Upvotes: 3

Related Questions