3

我目前正在尝试编译以下内容:

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();
  }
};

然而,由于存在两个可能的to_foo()成员,专业化变得混乱,因此它将选择默认情况。一旦我删除其中一个to_foo()成员,它就会起作用,但是其中一种callX()方法会失败,因为它与常量不匹配。

在这种情况下有什么方法可以检测到这个功能吗?

编辑

这是关于 ideone 的示例:http: //ideone.com/E6saX

当其中一种方法被删除时,它工作得很好:http: //ideone.com/iBKoN

4

3 回答 3

1

我仍然不清楚您要达到的目标。我会假设目标类型 ( foo) 是固定的,我们不会尝试创建全桥系统。

在这种情况下,我们可以放弃结构,只依靠重载选择。

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

就实际翻译而言,工作得很好。不涉及模板。

现在的问题可能是如何实际检测这种转换是否可行。在这种情况下,我们需要使用 SFINAE 来避免在尝试转换时出现硬错误。

#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
}

注意:在 Clang 3.0(有变通方法)和gcc 4.5.1上成功编译。

于 2012-03-06T10:29:27.050 回答
0

我对模板还不太了解,但似乎这is_const是您正在寻找的类型特征,以检查函数是否为const.

链接在这里

于 2012-03-06T09:41:47.487 回答
-1

我的 gcc(4.1.0) 不支持 c++0x,所以我删除了 std::enable_if 部分。然后它编译并成功运行。见:http: //ideone.com/KzasX

谢谢

于 2012-03-06T10:38:13.803 回答