在C++中使用匿名类实现接口

FaN*_*NaJ 6 c++ java interface anonymous-class

在java中我们可以interface用这样的Anonymous类实现:

import java.util.function.Predicate;

public class Test {

    public static void main(String[] args) {
        System.out.println(testIf("", new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.isEmpty();
            }
        }));
    }

    public static <T> boolean testIf(T t, Predicate<T> predicate) {
        return predicate.test(t);
    }

}
Run Code Online (Sandbox Code Playgroud)

从Java 8开始:

System.out.println(testIf("", String::isEmpty));
Run Code Online (Sandbox Code Playgroud)

我们怎么能用c ++做呢?我编写了以下代码但是我收到了编译错误:

#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;

template <class T>
class Predicate
{
public:
    virtual bool test(T) = 0;
};

template <class T>
bool testIf(T t, Predicate<T> predicate)
{
    return predicate.test(t);
}

int main()
{
    class : public Predicate <string> {
    public:
        virtual bool test(string s)
        {
            return s.length() == 0;
        }
    } p;
    string s = "";
    cout << testIf(s, p);
    cin.get();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

错误:没有函数模板"testIf"匹配参数列表参数类型的实例是:(std::string,class <unnamed>)

这有什么不对?还有其他办法吗?

谢谢!

Mik*_*our 9

这有什么不对?

要使多态性起作用,您需要通过引用(或指针,如果您愿意)传递基类:

bool testIf(T t, Predicate<T> & predicate)
                              ^
Run Code Online (Sandbox Code Playgroud)

修复后,代码对我有用,虽然它根据我的口味闻到了相当多的Java.

还有其他办法吗?

在C++ 11或更高版本中,lambda在性能和代码噪声方面都会更高效.它消除了从基类定义和继承以及调用虚函数的需要.

template <class T, class Predicate>
bool testIf(T t, Predicate predicate)
{
    return predicate(t);
}

testIf(s, [](string const & s){return s.length() == 0;});
Run Code Online (Sandbox Code Playgroud)

(在C++ 11之前,您可以使用函数对象执行相同的操作.它稍微冗长一点,但仍然提供比继承方法更短,更高效的代码.)