Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/164.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在C++;模板_Java_C++_Templates_Generics - Fatal编程技术网

Java 如何在C++;模板

Java 如何在C++;模板,java,c++,templates,generics,Java,C++,Templates,Generics,我有一小部分Java算法,用于玩多回合游戏,如Tictatcoe、Otherlo、Checkers等。我使用Java泛型(自定界类型)来实现这一点,以便能够使用相同的算法,而不必为每个游戏专门更改它们。这里没有显示我使用自定界类型的原因,但是求值函数需要它 public interface Game<GAME extends Game<GAME>> { GAME copy(); int getCurPlayer(); ... } public c

我有一小部分Java算法,用于玩多回合游戏,如Tictatcoe、Otherlo、Checkers等。我使用Java泛型(自定界类型)来实现这一点,以便能够使用相同的算法,而不必为每个游戏专门更改它们。这里没有显示我使用自定界类型的原因,但是求值函数需要它

public interface Game<GAME extends Game<GAME>> {
    GAME copy();
    int getCurPlayer();
    ...
}

public class TicTacToe implements Game<TicTacToe> {
    ...
    @Override
    public TicTacToe copy() {
        ...
    }
    @Override
    public int getCurPlayer() {
        ...
    }
    ...
}
当我尝试编译时,我得到的错误是:

out-of-line definition of 'copy' does not match any declaration in 'TicTacToe'

out-of-line definition of 'cur_player' does not match any declaration in 'TicTacToe'
。。。
对于其他每个纯虚函数也是如此。

您的定义也需要将
const
应用于它们。CRTP,正如它在C++中所知道的(奇怪的重复模板模式)是完全有效的C++。 但是,这里不需要
virtual
,CRTP用于静态分派功能并自动实现功能

template <typename T>
class Game
{
    T& crtp_cast() { return *static_cast<T*>(this); }
    const T& crtp_cast() const { return *static_cast<const T*>(this); }
public:
    T copy() const { return crtp_cast(); }
    int cur_player() const { return crtp_cast().cur_player(); }
    ...
};
模板
班级游戏
{
T&crtp_cast(){return*static_cast(this);}
const T&crtp_cast()const{return*static_cast(this);}
公众:
T copy()常量{return crtp_cast();}
int cur_player()常量{return crtp_cast().cur_player();}
...
};
注意,在这种情况下,派生类不需要实现“copy”函数,因为复制构造函数将被“copy”自动调用。然而,在一般情况下,由于模板是duck类型的,所以不需要做这种事情,通常您只需要使用标准模板。与Java的泛型不同,C++的模板与继承没有任何关系——可以实例化的类型不必从公共接口继承

template<typename Game> void f(const Game& g) {
    std::cout << g.cur_player();
}
class X {
public:
    int cur_player() const { return 1; }
};
class Y {
public:
    int cur_player() const { return 2; }
};
int main() {
    f(X());
    f(Y());
}
模板无效f(const Game&g){

STD::CUT< P>你的定义需要应用<代码> const 。CRTP,如C++中已知的(奇怪的重复模板模式)是完全有效的C++。 但是,这里不需要
virtual
,CRTP用于静态分派功能并自动实现功能

template <typename T>
class Game
{
    T& crtp_cast() { return *static_cast<T*>(this); }
    const T& crtp_cast() const { return *static_cast<const T*>(this); }
public:
    T copy() const { return crtp_cast(); }
    int cur_player() const { return crtp_cast().cur_player(); }
    ...
};
模板
班级游戏
{
T&crtp_cast(){return*static_cast(this);}
const T&crtp_cast()const{return*static_cast(this);}
公众:
T copy()常量{return crtp_cast();}
int cur_player()常量{return crtp_cast().cur_player();}
...
};
注意,在这种情况下,派生类不需要实现“copy”函数,因为复制构造函数将被“copy”自动调用但是,在一般情况下,由于模板是duck类型的,因此没有必要做这种事情,通常您只需要使用标准模板。与Java泛型不同,C++的模板与继承没有任何关系-可以实例化的类型不必从公共接口继承

template<typename Game> void f(const Game& g) {
    std::cout << g.cur_player();
}
class X {
public:
    int cur_player() const { return 1; }
};
class Y {
public:
    int cur_player() const { return 2; }
};
int main() {
    f(X());
    f(Y());
}
模板无效f(const Game&g){

std::cout而不是使用泛型/模板,我只会从copy之类的东西传递一个指向游戏的指针,然后如果您真的需要,动态地将其向下转换

例如:

游戏h:

class Game
{
public:
    virtual Game* copy() const = 0;
    virtual int cur_player() const = 0;
    ...
};
Tictoe.h:

class TicTacToe : public Game
{
public:
    virtual Game* copy() const;
    virtual int cur_player() const;
    ...
};
TicTacToe.cpp:

Game* TicTacToe::copy()
{
    ...
}

int TicTacToe::cur_player()
{
    ...
}
按以下方式创建游戏:

TicTacToe ttt;
Game* game = &ttt;
Game* nextGame = game->copy(); // this will call TicTacToe::copy
如果您需要调用TictaToe特定的方法,请将它们添加到游戏中,或者尝试向下播放:

TicTacToe* ttt = dynamic_cast<TicTacToe*>(game);
ttt->TTTSpecificMethod();
TicTacToe*ttt=动态施法(游戏);
ttt->TTTSSpecificMethod();

我不使用泛型/模板,而是通过复制之类的方式传递一个指向游戏的指针,然后如果您真的需要,动态地将其向下转换

例如:

游戏h:

class Game
{
public:
    virtual Game* copy() const = 0;
    virtual int cur_player() const = 0;
    ...
};
Tictoe.h:

class TicTacToe : public Game
{
public:
    virtual Game* copy() const;
    virtual int cur_player() const;
    ...
};
TicTacToe.cpp:

Game* TicTacToe::copy()
{
    ...
}

int TicTacToe::cur_player()
{
    ...
}
按以下方式创建游戏:

TicTacToe ttt;
Game* game = &ttt;
Game* nextGame = game->copy(); // this will call TicTacToe::copy
如果您需要调用TictaToe特定的方法,请将它们添加到游戏中,或者尝试向下播放:

TicTacToe* ttt = dynamic_cast<TicTacToe*>(game);
ttt->TTTSpecificMethod();
TicTacToe*ttt=动态施法(游戏);
ttt->TTTSSpecificMethod();
通过一些修改,自绑定泛型(Java)与奇怪的循环模板模式(C++)等价

template <class T>
class A
{
private:
  explicit A(A *temp) {}

public:
  explicit A() : A(static_cast<T*>(this)) {}
  virtual A* function(T *parameter) = 0;
};

class B final : public A<B>
{
public:
    B* function(B *parameter) { return new B(); }
};

class C final
{
};

class D final : public A<C>
{
public: // It occurs compile-time-error
  D* function(C *parameter) { return new D(); }
};

class E final : public A<E>
{
public: //"override" specifier will not be accepted due to signature does not match!
    E* function(E *parameter) override { return new E(); }
};

class F final : public A<B>
{
public: //You can also assign another relative type but type-self
    F* function(B *parameter) { return new F(); }
};

int main()
{
    return 0;
}
模板
甲级
{
私人:
显式A(A*temp){}
公众:
显式A():A(static_cast(this)){
虚A*函数(T*参数)=0;
};
B类期末考试:公共A
{
公众:
B*函数(B*参数){返回新的B();}
};
丙级决赛
{
};
D类期末考试:公共A
{
public://发生编译时错误
D*函数(C*参数){返回新的D();}
};
E级期末考试:公共A
{
public://“override”说明符将不被接受,因为签名不匹配!
E*函数(E*参数)重写{返回新的E();}
};
F类期末考试:公共A
{
public://您还可以指定另一个相对类型,但不能指定self类型
F*函数(B*参数){返回新的F();}
};
int main()
{
返回0;
}
通过一些修改,自绑定泛型(Java)与奇怪的循环模板模式(C++)等价

template <class T>
class A
{
private:
  explicit A(A *temp) {}

public:
  explicit A() : A(static_cast<T*>(this)) {}
  virtual A* function(T *parameter) = 0;
};

class B final : public A<B>
{
public:
    B* function(B *parameter) { return new B(); }
};

class C final
{
};

class D final : public A<C>
{
public: // It occurs compile-time-error
  D* function(C *parameter) { return new D(); }
};

class E final : public A<E>
{
public: //"override" specifier will not be accepted due to signature does not match!
    E* function(E *parameter) override { return new E(); }
};

class F final : public A<B>
{
public: //You can also assign another relative type but type-self
    F* function(B *parameter) { return new F(); }
};

int main()
{
    return 0;
}
模板
甲级
{
私人:
显式A(A*temp){}
公众:
显式A():A(static_cast(this)){
虚A*函数(T*参数)=0;
};
B类期末考试:公共A
{
公众:
B*函数(B*参数){返回新的B();}
};
丙级决赛
{
};
D类期末考试:公共A
{
public://发生编译时错误
D*函数(C*参数){返回新的D();}
};
E级期末考试:公共A
{
public://“override”说明符将不被接受,因为签名不匹配!
E*函数(E*参数)重写{返回新的E();}
};
F类期末考试:公共A
{
public://您还可以指定另一个相对类型,但不能指定self类型
F*函数(B*参数){返回新的F();}
};
int main()
{
返回0;
}

您从不说明什么不起作用。这根本不清楚为什么不起作用。您有什么问题(编译器错误?)没有“自绑定类型”的用处在Java中。你的代码在
公共界面游戏中同样有效。你从不说什么不起作用。为什么不起作用一点也不明显。你有什么问题(编译器错误?)没有“自绑定类型”的用处在Java中。您的代码与
公共界面游戏一样有效
谢谢,它有效!您