octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Compilation failure, template problems


From: Jaroslav Hajek
Subject: Re: Compilation failure, template problems
Date: Sun, 15 Nov 2009 21:21:43 +0100



On Sat, Nov 14, 2009 at 10:08 PM, Michael Goffioul <address@hidden> wrote:
On Sat, Nov 14, 2009 at 8:52 PM, Jaroslav Hajek <address@hidden> wrote:
>
>
> On Sat, Nov 14, 2009 at 4:31 PM, Michael Goffioul
> <address@hidden> wrote:
>>
>> Hi,
>>
>> Using recent octave archive, MSVC fails to compile liboctave due
>> to a template problems. The error is the following:
>>
>> ../../liboctave/CNDArray.cc(763) : error C2563: mismatch in formal
>> parameter list
>> ../../liboctave/CNDArray.cc(763) : error C2563: mismatch in formal
>> parameter list
>> ../../liboctave/CNDArray.cc(763) : error C2440: 'specialization' :
>> cannot convert from 'overloaded-function' to 'double (__cdecl *const
>> )(Complex)'
>>        None of the functions with this name in scope match the target type
>> ../../liboctave/CNDArray.cc(763) : error C2973: 'do_mx_unary_map' :
>> invalid template argument 'overloaded-function'
>>
>>  c:\sources\playground\c\octave-graphics-hg\liboctave\mx-inlines.cc(264)
>> : see declaration of 'do_mx_unary_map'
>> ../../liboctave/CNDArray.cc(763) : error C2668: 'do_mx_unary_map' :
>> ambiguous call to overloaded function
>>
>>  c:\sources\playground\c\octave-graphics-hg\liboctave\mx-inlines.cc(271):
>> could be 'RNDA do_mx_unary_map<NDArray,ComplexNDArray,double
>> std::abs<double>(const std::complex<double> &)>(const XNDA &)'
>>        with
>>        [
>>            RNDA=NDArray,
>>            XNDA=ComplexNDArray
>>        ]
>>
>>  c:\sources\playground\c\octave-graphics-hg\liboctave\mx-inlines.cc(264):
>> or       'RNDA do_mx_unary_map<NDArray,ComplexNDArray,& abs>(const
>> XNDA &)'
>>        with
>>        [
>>            RNDA=NDArray,
>>            XNDA=ComplexNDArray
>>        ]
>>        while trying to match the argument list '(const ComplexNDArray)'
>>
>> Any idea how to work around the problem? This part of the code seems
>> pretty recent.
>>
>> Michael.
>
> I think this should compile - name resolution for template function
> parameters works like for regular parameters. Here the signature is fully
> determined by the previous parameters, so a unique match should be found.
> So I think this is a bug in MSVC.
> Unfortunately, the typical way to pick a specific overload (cast the name
> reference to specific function pointer type) doesn't work in this case,
> because only integral and enum casts are allowed in template params. Maybe
> just specifying std::abs<double> instead of std::abs would work? Otherwise,
> I think you'll need to wrap std::abs in a function with unique name and
> substitute that for the template parameter.

I tried various things, but none of them work. For instance, the following:

double d_abs(double x) { return std::abs(x); }

NDArray
NDArray::abs (void) const
{
 return do_mx_unary_map<NDArray, NDArray, d_abs> (*this);
}

gives me the following error:

../../liboctave/dNDArray.cc(880) : error C2440: 'specialization' :
cannot convert from 'double (__cdecl *)(double)' to 'double (__cdecl
*const )(const double &)'
       This conversion requires a reinterpret_cast, a C-style cast or
function-style cast


Wicked. Why is it picking the wrong version? There are both `fun (T)' and `fun (const T&)' versions defined...
 
However, I think the problem is more than simply being unable
to resolve the ambiguity. It seems MSVC fails to handle the
situation correctly when dealing with inner types and/or overloaded
functions. For instance, the following works fine:

double g(double x) { std::cout << "g(double)" << std::endl; return x; }
int g(int x) { std::cout << "g(int)" << std::endl; return x; }
float g(float x) { std::cout << "g(float)" << std::endl; return x; }

template <class T, T fun(T)>
T h(T t)
{
 return fun(t);
}

int main(int argc, char **argv)
{
 std::cout << h<double,g>(-10) << std::endl;
 return 0;
}

I also think this is a bug in MSVC. I'm more interested in a
workaround. Otherwise, this will mean the game is over.

What about this?
If not, I'm out of ideas...

diff --git a/liboctave/mx-inlines.cc b/liboctave/mx-inlines.cc
--- a/liboctave/mx-inlines.cc
+++ b/liboctave/mx-inlines.cc
@@ -259,14 +259,7 @@
 
 // Shortcuts for applying mx_inline_map.
 
-template <class RNDA, class XNDA, AELEMT(RNDA) fun (AELEMT(XNDA))>
-inline RNDA
-do_mx_unary_map (const XNDA& x)
-{
-  return do_mx_unary_op<RNDA, XNDA> (x, mx_inline_map<AELEMT(RNDA), AELEMT(XNDA), fun>);
-}
-
-template <class RNDA, class XNDA, AELEMT(RNDA) fun (const AELEMT(XNDA)&)>
+template <class RNDA, class XNDA, AELEMT(RNDA) fun (typename ref_param<AELEMT(XNDA)>::type)>
 inline RNDA
 do_mx_unary_map (const XNDA& x)
 {


--
RNDr. Jaroslav Hajek
computing expert & GNU Octave developer
Aeronautical Research and Test Institute (VZLU)
Prague, Czech Republic
url: www.highegg.matfyz.cz

reply via email to

[Prev in Thread] Current Thread [Next in Thread]