- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
While compiling code, that should check for the existance of a template member function with explicit parameter, compiler fails with
error: type name is not allowed
template <typename _1> static true_t Test(_1* p, decltype(p->StaticInterfaceCast<interfaceT>())* = nullptr);
problem is unrelated to decltype but to explicit template parameters on member functions. On vs2012 code compiles.
This is the test mpl compatible predicate
template <typename T, typename interfaceT> struct HasStaticInterfaceCast
{
typedef char true_t[1];
typedef char false_t[2];
template <typename _1> static false_t Test(...);
template <typename _1> static true_t Test(_1* p, decltype(p->StaticInterfaceCast<interfaceT>())* = nullptr);
static value_type const value = sizeof(Test<T>((T*)0)) == sizeof(true_t);
};
And the test code --- ofc, cannot be executed, because compilation of predicate fails
struct Interface;
struct Tester
{
template <typename T> boost::enable_if<boost::is_same<T,Interface>,T>::type* StaticInterfaceCast() const;
};
BOOST_MPL_ASSERT((HasStaticInterfaceCast<Tester,Interface>));
Is there any know workaround ? Because it keeps me from migrating the source code.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It looks like Microsoft doesn't require the template keyword (but should). Since there's no way of knowing whether StaticInterfaceCast is a template or not (because the type of p is a dependent template) the template keyword is required. The fix/workaround will require with our compiler, GNU, and Microsoft. The code as is will only compile with Microsoft.
A workaround/fix is:
template <typename T, typename interfaceT> struct HasStaticInterfaceCast
{
typedef char true_t;
typedef char false_t;
template <typename _1> static false_t Test(...);
template <typename _1> static true_t Test(_1* p,
#ifdef OK
decltype(p->template StaticInterfaceCast<interfaceT>())* = nullptr);
#else
decltype(p->StaticInterfaceCast<interfaceT>())* = nullptr);
#endif
static bool const value = sizeof(Test<T>((T*)0)) == sizeof(true_t);
};
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For more info on why/when the template keyword is required see:
http://stackoverflow.com/questions/4077110/template-disambiguator
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks for your quick help, so I just got the syntax wrong.
If I then apply a negative check, it fails, because it tries to resolve the member function which its no there. As far as I understand it, SFINAE should no pick that Test function at all. Again no problem with msvc11, but maybe it is just another syntax problem ?
struct Negative {};
BOOST_MPL_ASSERT_NOT(HaStaticInterfaceCast<Negative,Interface>));
fails with compiler error
error #308: function "Negative::StaticInterfaceCast<interfa
ceT>() const [with interfaceT=Interface]" is inaccessible
template <typename _1> static true_t Test(_1* p, decltype(p->template StaticInterfaceCast<interfaceT>())* = nullptr);
Any hint for that problem ?
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page