Prev: C++ FAQ
Next: Member Initialization Lists
From: Jesse Perla on 10 Jun 2010 10:13 (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 |