【问题标题】:template to check for existence of overloaded member function检查是否存在重载成员函数的模板
【发布时间】:2012-11-12 10:04:22
【问题描述】:

如果一个类有这样的特殊成员函数(在另一个例子中找到),我会尝试专门化一个模板:

template <typename T>
class has_begin
{
    typedef char one;
    typedef long two;

    template <typename C> static one test( decltype( &C::AnyFunc) ) ;
    template <typename C> static two test(...);

public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
    enum { Yes = sizeof(has_begin<T>::test<T>(0)) == 1 };
    enum { No = !Yes };
};

这在AnyFunc 过载之前运行良好:

class B : public vector<int>
{
public:
    void AnyFunc() const;
    void AnyFunc();
};

如何重写我的测试代码以从我的模板中获得“是”?

【问题讨论】:

  • 好问题。一个非常微不足道的问题,由于 SFINAE,它可能会被悄悄地检测到。

标签: c++ templates metaprogramming


【解决方案1】:

使用不带参数的重载函数名 (13.4p1) 必须解析为单个重载 (13.4p4),否则会发生替换失败。

如果您正在测试成员函数的存在,那么您应该知道您计划调用它的参数:

    template <typename C> static one test(
        typename std::add_pointer<decltype(std::declval<C>().AnyFunc())>::type);

一般情况下,您可以使用可变参数模板和类似于result_of 的模式:

    template <typename C, typename... Args> static one test(
        typename std::add_pointer<decltype(
            std::declval<C>(std::declval<Args>()...).AnyFunc())>::type);

使用add_pointer 允许它处理不允许作为函数参数类型的函数返回类型(例如void)。

【讨论】:

    【解决方案2】:

    找到有效的版本:

        template <typename C> static one test( decltype(((C*)0)->AnyFunc())* ) ;
    

    如果要验证对象是否具有 const 函数,请使用:

        template <typename C> static one test( decltype(((const C*)0)->AnyFunc())* ) ;
    

    这个版本不会检测带参数的函数:

    class B : public std::vector<int>
    {
    public:
        //void AnyFunc() const;
        //void AnyFunc();
        int AnyFunc(int);
    };
    

    【讨论】:

    • @Klaus 这就是为什么我在decltype() 之后添加*...我在发布之前检查它是否有效:ideone.com/8Tli7t
    • 阅读第二个答案后,我得到了您的解决方案,可以在我的环境中运行。非常感谢!
    • 是的,我忘记了 decltype 后面的 *!对不起我的错!从第二个答案中查看 std::add_pointer 之后,我得到了这个工作。
    • std::add_pointer 比简单的 * 更好,因为您不能有指向引用的指针。另一方面,它是一个新的 C++11 特性,并不总是实现(尤其是在旧版本的编译器中)
    猜你喜欢
    • 2018-11-23
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-15
    相关资源
    最近更新 更多