2012-03-06 58 views
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

+1

这是一个有点不清楚你正试图在这里实现什么。如果你能说明使用'convert'会更好,这样我们就可以看到你想要达到的目标,而不是迷失在当前尝试解决问题的细节中。 – 2012-03-06 09:45:45

+0

@MatthieuM .:这是一个更加复杂的大型框架的一部分,它处理多种类型。对于某些类型的转换是必要的,然后才能使用。不过,我需要一种方法来检测如何转换和转换为这些转换类型,因为这高度依赖于输入类型。给定的代码是这个小部分,我目前正在努力工作。 – LiKao 2012-03-06 09:52:35

回答

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 
} 

注:编译成功上锵3.0(与变通)和gcc 4.5.1

+0

啊,我明白了。在我遇到错误的情况下,额外的间接帮助。现在我只是通过强制一个方法从'to_foo()'重命名为'to_const_foo()'来解决这个问题。然而,这更糟糕,因为这两种方法确实做了同样的事情,所以它们应该有相同的名称。我会看看我是否可以采用你的方法。 – LiKao 2012-03-06 11:33:04

0

我不很了解模板,但似乎is_const是您正在寻找的类型特征,检查功能是否const

链接here

+0

虽然困难在于'T :: to_foo'不能被推导出来,因为这个方法被重载了。对于重载的方法,需要'static_cast'到正确的签名。 – 2012-03-06 10:05:17

+0

不,'is_const'显然没有帮助,因为我只是试图找出方法是否存在。除了后面的部分,我并不关心常量。我可能不得不将'convert'类稍后分成处理常量和非常量的部分,但是这并不能解决检测重载方法存在的问题。 – LiKao 2012-03-06 10:06:33

相关问题