Home Dashboard Directory Help
Search

C++ type equality not recognized under SFINAE context by Bronek


Status: 

Closed
 as Fixed Help for as Fixed


1
0
Sign in
to vote
Type: Bug
ID: 718729
Opened: 1/15/2012 3:04:51 PM
Access Restriction: Public
Moderator Decision: Sent to Engineering Team for consideration
1
Workaround(s)
view
0
User(s) can reproduce this bug

Description

Template like the following may fail (under SFINAE context, so it's quiet failure) when both parameters are same type, and type T is a pointer to template specialization

template <typename T, T> struct same_ { typedef void* type; };

Outside of SFINAE context, similar code works as intended.
Details
Sign in to post a comment.
Posted by Bronek on 1/16/2012 at 2:30 PM
Actual workaround posted in "Workarounds" tab
Posted by Bronek on 1/16/2012 at 12:55 PM
Ooops, code posted at 16/01/2012 at 12:13 is not working workaround, it disables SFINAE.
Posted by Bronek on 1/16/2012 at 12:13 PM
Thank you - great to know this is fixed!

For those stuck with the current version, here is workaround:

template <typename A> struct testme{};

typedef char true_;
typedef int false_;
template <typename T, T> struct same_ { typedef void* type; };

template <typename A>
struct has_path_
{
typedef testme<int> A::*f;
static false_ select(...);
static true_ select(typename same_<f, &A::path>::type);
};

template <typename A>
struct has_path
{
enum { value = sizeof(has_path_<A>::select(0)) == sizeof(true_) };
};

struct get
{
testme<int> path;
};

int main()
{
int t[(int)has_path<get>::value];
(void)t;
}
Posted by Microsoft on 1/16/2012 at 12:05 PM
Hi:
    A fix for this issue has been checked into the compiler sources. The fix should show up in the next release of Visual C++.

Xiang Fan
Visual C++ Team
Posted by MS-Moderator07 [Feedback Moderator] on 1/15/2012 at 7:12 PM
Thanks for your feedback.

We are rerouting this issue to the appropriate group within the Visual Studio Product Team for triage and resolution. These specialized experts will follow-up with your issue.
Posted by MS-Moderator01 on 1/15/2012 at 3:41 PM
Thank you for your feedback, we are currently reviewing the issue you have submitted. If this issue is urgent, please contact support directly(http://support.microsoft.com)
Sign in to post a workaround.
Posted by Bronek on 1/16/2012 at 2:30 PM
Split detection into 2 phase process, use SFINAE only to detect presence of name.

In the second stage don't use SFINAE, just a specialized template for a match with signature.


#include <string>

// First stage
template <typename T> struct has_data
{
struct F {int data;};
struct D : T, F {};
template <typename U, U> struct same_;

template <typename C> static char(&select(same_<int F::*, &C::data>*))[1];
template <typename> static char(&select(...))[2];
enum {value = sizeof(select<D>(0)) == 2};
};

// Second stage - no name match
template <bool, typename>
struct has_data_string_match_ { enum {value = false};};

// Second stage - name match, detect equality of type
template <typename T>
struct has_data_string_match_<true, T>
{
template <typename U, typename V> struct match_ { enum {value = false};};
template <typename V> struct match_<V,V> { enum {value = true};};

// enum {value = match_<std::string (*) (), decltype...
// enum {value = match_<std::string (T::*) () const, decltype...
// enum {value = match_<const std::string*, decltype...
enum {value = match_<std::string T::*, decltype(&T::data)>::value};
};

template <typename T>
struct has_data_string : has_data_string_match_<has_data<T>::value, T>
{};

struct get
{
// See above for matching signatures
// static std::string data();
// std::string data() const;
// static const std::string data;
std::string data;
};

int main()
{
int t[(int)has_data_string<get>::value];
(void)t;
}