How to properly validate a (const) overloaded method

I am currently trying the following:

class foo {
};

class bar {
public:
  const foo & to_foo() const {
    return f;
  }

  foo & to_foo() {
    return f;
  }
private:
 foo f;
};

template< typename T, typename Enable = void >
class convert {};

template< typename T >
struct convert< T, typename std::enable_if< std::is_member_function_pointer< decltype( &T::to_foo ) >::value >::type > {

  static const foo & call1( const bar & b ) {
    return b.to_foo();
  }

  static foo & call2( bar & b ) {
    return b.to_foo();
  }
};

      

However, the specialization gets confused by having two possible members to_foo()

, so it will choose the default case. As soon as I remove one of the members to_foo()

, it works, but then one of the methods callX()

fails because it doesn't match the constant.

Is there a way to detect this feature in this case?

EDIT

Here's an example on ideone: http://ideone.com/E6saX

When one of the methods is removed it works great: http://ideone.com/iBKoN

+3


source to share


3 answers


I'm still a bit confused about what you are trying to achieve. I am assuming that the target type ( foo

) is fixed and we are not trying to create a complete bridging system.

In this case, we can drop the structure and just rely on the choice of overload.

foo const& to_foo(bar const& b) { return b.to_foo(); }
foo& to_foo(bar& b) { return b.to_foo(); }

      

Works great as far as real translation goes. No template is involved.



Now the question may arise how to determine if this conversion is possible or not. In this case, we need to use SFINAE to avoid a hard error when trying to convert.

#include <iostream>
#include <utility>

// Didn't remember where this is implemented, oh well
template <typename T, typename U> struct same_type: std::false_type {};
template <typename T> struct same_type<T, T>: std::true_type {};

// Types to play with
struct Foo {};
struct Bar { Foo _foo; };
struct Bad {};

Foo const& to_foo(Bar const& b) { return b._foo; }
Foo& to_foo(Bar& b) { return b._foo; }

// Checker
template <typename T>
struct ToFoo {
  T const& _crt;
  T& _rt;

  template <typename U>
  static auto to_foo_exists(U const& crt, U& rt) ->
      decltype(to_foo(crt), to_foo(rt), std::true_type());

  static std::false_type to_foo_exists(...);

  // Work around as the following does not seem to work
  // static bool const value = decltype(to_foo_exists(_crt, _rt))::value;
  static bool const value = same_type<
                                decltype(to_foo_exists(_crt, _rt)),
                                std::true_type
                            >::value;
};

// Proof
int main() {
  std::cout << ToFoo<Bar>::value << "\n"; // true
  std::cout << ToFoo<Bad>::value << "\n"; // false
}

      

Note: Successfully compiled with Clang 3.0 (at work) and gcc 4.5.1 .

+1


source


I don't know much about templates yet, but it seems that is_const

is the type you are looking for to check if there is a function const

.



Link here

0


source


my gcc (4.1.0) does not support C ++ 0x, so I remove the std :: enable_if part. then it compiles and runs successfully. see: http://ideone.com/KzasX

thank

-1


source







All Articles