unable to resolve template parameter

N

Noah Roberts

What is wrong with the following code because I just can't see it:

#include <string>
#include <iostream>

namespace something {

template < typename R, typename T >
inline R f(T const& x)
{
return R(x);
}
}

template < typename T >
struct test
{
test(double d = something::f<double>(5))
: test_double(d) {}

double test_double;
};

int main()
{
test<int> t;

std::cout << t.test_double;

std::cin.get();
}

The compiler complains that it cannot resolve R in the call to
something::f<double>() in the test constructor. It only happens in
default arguments and only if you need namespace resolution to get to f
<>.

If the line "test(double d = something::f<double>(5))" is changed to
"test(double d = f<double>(5))" and a "using namespace something" is
placed above the structure declaration, the code compiles just fine.

Here's the actual compiler error:

1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2783: 'R something::f(const T &)' : could not deduce template argument
for 'R'
1> d:\dev_workspace\experimental\scratch\scratch\main.cpp(7) :
see declaration of 'something::f'

This makes no sense to me at all. Am I running into some obscure C++
standard thing or is this compiler just broken?

This was actually discovered in an attempt to provide a string default
argument through a boost::lexical_cast.
 
G

Gert-Jan de Vos

What is wrong with the following code because I just can't see it:

#include <string>
#include <iostream>

namespace something {

  template < typename R, typename T >
  inline R f(T const& x)
  {
    return R(x);
  }

}

template < typename T >
struct test
{
  test(double d = something::f<double>(5))
    : test_double(d) {}

  double test_double;

};

int main()
{
  test<int> t;

  std::cout << t.test_double;

  std::cin.get();

}

The compiler complains that it cannot resolve R in the call to
something::f<double>() in the test constructor.

Comeau C++ compiles it so it is probably a compiler bug.
 
L

luther13

As f() is a template of 2 typename,
you must call:
something::f<typename R,double>(5)


"Gert-Jan de Vos" <[email protected]> a écrit dans le
message de
(e-mail address removed)...
What is wrong with the following code because I just can't see it:

#include <string>
#include <iostream>

namespace something {

template < typename R, typename T >
inline R f(T const& x)
{
return R(x);
}

}

template < typename T >
struct test
{
test(double d = something::f<double>(5))
: test_double(d) {}

double test_double;

};

int main()
{
test<int> t;

std::cout << t.test_double;

std::cin.get();

}

The compiler complains that it cannot resolve R in the call to
something::f<double>() in the test constructor.

Comeau C++ compiles it so it is probably a compiler bug.
 
N

Noah Roberts

As f() is a template of 2 typename,
you must call:
something::f<typename R,double>(5)

I think you've misunderstood. The 'double' parameter supplied is not
meant to say what the function argument type is, that is meant to be
resolved by the compiler. The return type 'R' is what is being supplied
and it's being supplied at the call site, like it should be. This is
valid in C++, so long as your supplied types come before your resolved
types in the parameter list, and usually works just fine.

As I expected, the compiler doesn't even think what you've provided is
syntatically valid:


1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2146: syntax error : missing ',' before identifier 'R'
1> d:\dev_workspace\experimental\scratch\scratch\main.cpp(21) :
see reference to class template instantiation 'test<T>' being compiled
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2065: 'R' : undeclared identifier
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2146: syntax error : missing ',' before identifier 'R'
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2146: syntax error : missing ',' before identifier 'R'
1> d:\dev_workspace\experimental\scratch\scratch\main.cpp(25) :
see reference to class template instantiation 'test<T>' being compiled
1> with
1> [
1> T=int
1> ]
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2146: syntax error : missing ',' before identifier 'R'
1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2783: 'R something::f(const T &)' : could not deduce template argument
for 'R'
1> d:\dev_workspace\experimental\scratch\scratch\main.cpp(7) :
see declaration of 'something::f'

There's no syntatically valid way to specify that you want the compiler
to resolve a template parameter that comes before one you're explicitly
supplying.

Explicitly providing the argument type parameter at the call site
doesn't cause the original problem to go away either. As in changing
the test constructor to "test(double d = something::f<double, int>(5))"
still causes a compiler complaint about R being unresolvable.
 
N

Noah Roberts

@b2g2000yqi.googlegroups.com>, (e-mail address removed)
says...
Comeau C++ compiles it so it is probably a compiler bug.

That's really where I'm leaning too. It's just such a basic, everyday
use that I'm pretty blown away that it made it through QA. I guess
that's just MS for you though.
 
J

James Kanze

@b2g2000yqi.googlegroups.com>, (e-mail address removed)
says...

G++ does as well, and I can't think of anything in the standard
which would make this a special case.
That's really where I'm leaning too. It's just such a basic,
everyday use that I'm pretty blown away that it made it
through QA. I guess that's just MS for you though.

IIRC, you said that it only occurs in default arguments, and
only if there is a namespace qualifier. Which means that it is
a result of some faulty interaction between different features.
Off hand, it makes me wonder about the design of the compiler
(no encapsulation?), but it doesn't surprise me too much that it
slipped through quality control: given the number of features of
C++, you can't really test all possible combinations.
 
T

Triple-DES

What is wrong with the following code because I just can't see it:
[...]

Here's the actual compiler error:

1>d:\dev_workspace\experimental\scratch\scratch\main.cpp(17) : error
C2783: 'R something::f(const T &)' : could not deduce template argument
for 'R'
1>        d:\dev_workspace\experimental\scratch\scratch\main.cpp(7) :
see declaration of 'something::f'

This makes no sense to me at all.  Am I running into some obscure C++
standard thing or is this compiler just broken?

This was actually discovered in an attempt to provide a string default
argument through a boost::lexical_cast.

I reproduced the same issue with the following code:

namespace ns { template<typename T> T f(); }
struct C { C( int i = ns::f<int>() ); }; // C2783
int main() {}

Clearly the diagnostic is erroneous since there shouldn't be any
template argument deduction for this program. I have reported it to
Microsoft here:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=518117#details
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top