我目前正在尝试进行以下编译:
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()
方法中的一个失败了,因为它与constness不匹配。
在这种情况下有没有办法检测这个功能?
修改:
以下是关于ideone的示例:http://ideone.com/E6saX
当删除其中一个方法时,它可以正常工作:http://ideone.com/iBKoN
答案 0 :(得分: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。
答案 1 :(得分:0)
我对模板还不太了解,但似乎is_const
是您正在寻找的类型特征,以检查该函数是否为const
。
链接here
答案 2 :(得分:-1)
我的gcc(4.1.0)不支持c ++ 0x,所以我删除了std :: enable_if部分。然后它编译并成功运行。 看到: http://ideone.com/KzasX
感谢