From: Jesse Perla on
(I attempted to post this to comp.std.c++ but it didn't seem to pass
moderation, so I thought this is a 2nd best location)

While doing some meta-programming for choosing a return type of an
overloaded function, I ran into a problem with the expansion of
templates in the return type of overloaded functions (that are
rejected in the overload for other reasons). A version at the bottom
is attached, though a link on intel simplifies the problem a little.

The code works fine in g++/MinGW (I am using 4.4).

However, on Intel 11.1 and MSVC10, it fails since it tries to
instantiate the my_meta1<> even though the overload isn't used.

Intel responded that the standard was a little gray here but they are
making the following change: http://software.intel.com/en-us/forums/showpost.php?p=120228

Microsoft on the other hand says that this is by design:
" this is a grey area that the C++03 standard does not address;
however, the most current draft (n3090) of the C++0x standard
(14.9.2/8) states the following:
'Only invalid types and expressions in the immediate context of the
function type and its template parameter types can result in a
deduction failure.'
Therefore, this behavior is by-design. Since a deduction failure does
not occur, the program is considered ill-formed and an error is
emitted."
(See http://connect.microsoft.com/VisualStudio/feedback/details/560886/bug-in-template-expansion-during-function-overload-resolution
)

Do you think the Microsoft interpretation is correct? If so, is this
a 'bug' in the current C++0X standard? I think that the pattern above
comes up frequently in meta-programming where return types become
complicated and the only way around it seems to be some godawful
metaprogramming.

Thanks,
Jesse

//////////////////////////////
struct tag1{};
struct tag2{};
struct data1{
typedef double value;
};

struct data2{ //Doesn't have a ::value member
};

template<typename T>
struct my_meta1
{
typedef typename T::value value;
};

template<typename T>
struct my_meta2
{
typedef double value;
};

//Matching the function based on the tag type
template<typename DataType>
typename my_meta1<DataType>::value
f(tag1, DataType data)
{
return 0.0;
}

template<typename DataType>
typename my_meta2<DataType>::value
f(tag2, DataType data)
{
return 0.0;
}

int main()
{
f(tag1(), data1()); //Should match the tag1 specialization,
which in turn gets the metadata from the data1() struct
f(tag2(), data2()); //Should match the tag2 specialization,
which doesn't need to call anything on data2()\
return 0;
}
/////////////////////////

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 | 
Pages: 1
Prev: C++ FAQ
Next: Member Initialization Lists