My code is :
std::vector<double> Vec;
template<typename T>
void GetObj(VARIANT &vtProp)
{
CComSafeArray<T> SafeArray;
SafeArray.Attach(vtProp.parray);
ULONG Count = SafeArray.GetCount();
Vec.resize(Count);
for(ULONG Index = 0; Index < Count; Index++)
{
Vec[Index] = SafeArray[Index];
}
}
while compilation I got the error below:
error C2783: 'void __cdecl GetObj(struct tagVARIANT &)' : could not deduce template argument for 'T'
Kindly suggest me the correct answer
There is nothing in the function template's signature that allows the compiler to deduce the template type, so you need to be explicit:
GetObj<TheActualType>(arg);
Related
include
template <typename R, typename S, typename T>
T const min (R const& a, S const& b)
{
T val;
if( a > b )
{
val = static_cast<T>( b );
}
else
{
val = static_cast<T>( a );
}
return val;
}
// CANNOT change anything above this line --------------------
void B()
{
int val =0;
// Only change the next line
val = min (5,4.2);
assert( val == 4 );
}
when the code is compiled the following error is thrown
error C2783: 'const T min(const R &,const S &)' : could not deduce template argument for 'T'
Stuck trying to solve this.. . any help will be appreciated
The compiler error is telling you that it can't figure out what type T is supposed to be in your call to min, since you haven't specified it and the return type of a function or function template are not used during overload resolution or template argument deduction (unless it's a conversion operator, of course).
Since you can't change the definition of min (which is stupid) your only choice is to explicitly specify T in the call. However, since T is the last template parameter, you have to specify the two preceding template arguments too! Like this:
val = min<int, double, int>(5, 4.2);
The compiler cannot deduce the template argument if you don't use it.
That being said what you would do in this situation is specify in specify the template arguments when you call the function min. Just like this:
void B()
{
int val = 0;
// Only change the next line
val = min<int, double, int>(5, 4.2);
assert(val == 4);
}
I have a function template that takes a vector and an element of a given type and returns the position of the element in the vector. This is the code for this function template:
template<class T>
int findElement(const vector<T> &vec, const T &ele)
{
for(size_t i = 0; i < vec.size(); i++)
{
if(ele == vec[i])
return i;
}
return -1;
}
And here's the function call:
findElement<double>(intVec, ele);
But I get this error when I call the function:
error C2664: 'findElement' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'const std::vector<_Ty,_Ax> &'
And this error is same even if I remove the const for the vector in the function template definition:
error C2664: 'findElement' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'std::vector<_Ty,_Ax> &'
However, when I make the function call as
findElement(intVec, ele)
I do not get any error.
What is the reason for this behavior?
Seems like compiler cannot convert vector<double> to vector<int>. Since by logic way, intVec is vector of ints, isn't it? And you say compiler, that you want vector of doubles.
You cannot convert vector<T> to vector<U>, since vector has no following conversion constructor, and it's nice.
I have compiled the below code :
typedef unsigned char uint8;
template <uint8 N> inline uint8 g(uint8 x) { return x > N ? 1 : 0; }
template <size_t stride, size_t boxsize, class T, class F>
inline void boxfilt(size_t width, size_t size, T * inout, const F & f) {
}
template <class T> inline T self(const T & x) { return x; }
template <size_t stride, size_t boxsize, class T>
inline void boxfilt(size_t width, size_t size, T * inout) {
return boxfilt<stride, boxsize>(width, size, inout, self<T>);
}
int main(int argc, char* argv[])
{
uint8 *out = NULL;
boxfilt<3,4>(10,29,out,g<4>);
return 0;
}
In g++ compiler, it works fine. When I try to compile the same code in Visual Studio 2008 compiler, it shows the following error:
Error 1 error C2780: 'void boxfilt(size_t,size_t,T *)' : expects 3 arguments - 4 provided g:\testfjx\test\test.cpp
Error 2 error C2784: 'void boxfilt(size_t,size_t,T *,const F &)' : could not deduce template argument for 'overloaded function type' from 'overloaded function type' g:\testfjx\test\test.cpp
Error 3 error C2784: 'void boxfilt(size_t,size_t,T *,const F &)' : could not deduce template argument for 'T *' from 'uint8 *' g:\testfjx\test\test.cpp
How can I resolve this problem?
It is OK, in Visual C++ 2008 too.
If both VC++2008 and G++4.7.2 accept the code and VC++2005 doesn't, so maybe VC++2005 has bug, maybe it doesn't implement C++ specification completely.
I'm trying to overload a Sum function which accepts a [list or vector] start and end iterator as arguments. This compiler error is really confusing me. Relevant code is as follows:
template <typename T1, typename T2>
const double Sum(const typename T1::const_iterator& start_iter, const typename T2::const_iterator& end_iter)
{// overloaded function that calculates sum between two iterators
typename T1::const_iterator iterator_begin = start_iter;
typename T2::const_iterator iterator_end = end_iter;
double my_sum = 0;
for (iterator_begin; iterator_begin != iterator_end; iterator_begin++)
my_sum += *iterator_begin;
return my_sum;
}
int main()
{
list<double> test_list(10,5.1);
cout << Sum(test_list.begin(), test_list.end()); // compiler errors here
}
I get the following compiler errors:
iterators.cpp(72): error C2783: 'const double Sum(const
T1::const_iterator &,const T2::const_iterator &)' : could not deduce
template argument for 'T1'
iterators.cpp(72): error C2783: 'const double Sum(const
T1::const_iterator &,const T2::const_iterator &)' : could not deduce
template argument for 'T2'
iterators.cpp(72): error C2780: 'const double Sum(const
std::map &)' : expects 1 arguments - 2 provided
iterators.cpp(72): error C2780: 'const double Sum(const T &)' :
expects 1 arguments - 2 provided
How is the compiler not recognizing I'm trying to call the Sum function with two inputs? I'm calling the function incorrectly?
Thanks!
You dont need to tell it that iterators have to be members of some types T1 and T2, just template it on iterator type itself:
template <typename Iter>
const double Sum(Iter iterator_begin, Iter iterator_end)
{
double my_sum = 0;
for (; iterator_begin != iterator_end; ++iterator_end)
my_sum += *iterator_begin;
return my_sum;
}
int main()
{
std::list<double> test_list;
std::cout << Sum(test_list.begin(), test_list.end());
return 0;
}
also there is a standard std::accumulate that does this:
int main()
{
std::list<double> test_list;
std::cout << std::accumulate(test_list.begin(), test_list.end(), 0.0);
return 0;
}
First, I don't think you want to do this. Not all sequences have an
underlying container. (Think of istream_iterators, for example.) And
more importantly, you're distinctly allowing (and even encouraging)
begin and end iterators from different containers; there is no case
where you could legally use this function where T1 and T2 have
different types. The template should have a single parameter, which
should be an iterator; and by convention, the constraints on the
iterator should be expressed in the name of the parameter, e.g.
InputIterator (the case here), ForwardIterator, etc.
As to why your code doesn't compile:
In most cases, the types, templates, and non-type values that are used
to compose P participate in template argument deduction. That is, they
may be used to determine the value of a template argument, and the
value so determined must be consistent with the values determined
elsewhere. In certain contexts, however, the value does not
participate in type deduction, but instead uses the values of template
arguments that were either deduced elsewhere or explicitly specified.
If a template parameter is used only in non-deduced contexts and is
not explicitly specified, template argument deduction fails.
The non-deduced contexts are:
— The nested-name-specifier of a type that was specified using a
qualified-id.
[...]
(From §14.8.2.5/4,5.)
Call method like this..
Sum<list<double>,list<double> >(test_list.begin(), test_list.begin());
Consider the following code
template <typename T, T one>
T exponentiel(T val, unsigned n) {
T result = one;
unsigned i;
for(i = 0; i < n; ++i)
result = result * val;
return result;
}
int main(void) {
double d = exponentiel<double,1.0>(2.0f,3);
cout << d << endl;
return 0;
}
The compiler tells me this
no matching function for call to 'exponentiel(float, int)'
Why?
What's strange is that exponentiel works with int.
The problem is with the T one and the 1.0 in the template argument list.
You can't have a nontype template parameter of a floating point type and you can't pass a floating point value as a template argument. It's just not allowed (to the best of my knowledge, there's no really good reason why it's not allowed).
g++'s error message here is rather unhelpful. Visual C++ 2010 reports the following on the line where the template is used in main:
error C2993: 'double' : illegal type for non-type template parameter 'one'
Comeau Online reports:
line 13: error: expression must have integral or enum type
double d = exponentiel<double,1.0>(2.0f,3);
^
line 2: error: floating-point template parameter is nonstandard
template <typename T, T one>
^