我使用curiously recurring template pattern:如何在奇怪的循環模板模式中使用基類中的unordered_map?
#include <unordered_map>
using namespace std;
template<class S>
struct State {
unordered_map<int, S> children; // <-- problem!
};
struct TicTacToeState : public State<TicTacToeState> {
// implementation
};
int main() {
return 0;
}
基本上,我想有孩子的unordered_map在(基地)國家規定。
編譯g++ file.cpp -std=c++11
:
In file included from /usr/include/c++/4.8/utility:70:0,
from /usr/include/boost/config/no_tr1/utility.hpp:21,
from /usr/include/boost/config/select_stdlib_config.hpp:37,
from /usr/include/boost/config.hpp:40,
from /usr/include/boost/functional/hash/hash_fwd.hpp:17,
from /usr/include/boost/functional/hash/hash.hpp:13,
from /usr/include/boost/functional/hash.hpp:6,
from tests/../examples/tic_tac_toe.cpp:1,
from tests/test_tic_tac_toe.cpp:3:
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘struct std::pair<const long unsigned int, TicTacToeState>’:
/usr/include/c++/4.8/type_traits:615:28: required from ‘struct std::__is_destructible_impl<std::pair<const long unsigned int, TicTacToeState> >’
/usr/include/c++/4.8/type_traits:637:12: required from ‘struct std::__is_destructible_safe<std::pair<const long unsigned int, TicTacToeState>, false, false>’
/usr/include/c++/4.8/type_traits:652:12: required from ‘struct std::is_destructible<std::pair<const long unsigned int, TicTacToeState> >’
/usr/include/c++/4.8/type_traits:116:12: required from ‘struct std::__and_<std::is_destructible<std::pair<const long unsigned int, TicTacToeState> >, std::__is_direct_constructible_impl<std::pair<const long unsigned int, TicTacToeState>, const std::pair<const long unsigned int, TicTacToeState>&> >’
/usr/include/c++/4.8/type_traits:817:12: required from ‘struct std::__is_direct_constructible_new_safe<std::pair<const long unsigned int, TicTacToeState>, const std::pair<const long unsigned int, TicTacToeState>&>’
/usr/include/c++/4.8/type_traits:895:12: [ skipping 5 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/c++/4.8/type_traits:974:12: required from ‘struct std::is_copy_constructible<std::pair<const long unsigned int, TicTacToeState> >’
/usr/include/c++/4.8/bits/alloc_traits.h:540:12: required from ‘struct std::__is_copy_insertable<std::allocator<std::pair<const long unsigned int, TicTacToeState> > >’
/usr/include/c++/4.8/bits/alloc_traits.h:560:63: required by substitution of ‘template<class _Alloc> using __check_copy_constructible = std::__allow_copy_cons<std::__is_copy_insertable<_Alloc>::value> [with _Alloc = std::allocator<std::pair<const long unsigned int, TicTacToeState> >]’
/usr/include/c++/4.8/bits/unordered_map.h:97:11: required from ‘class std::unordered_map<long unsigned int, TicTacToeState, std::hash<long unsigned int>, std::equal_to<long unsigned int>, std::allocator<std::pair<const long unsigned int, TicTacToeState> > >’
tests/../examples/../gtsa.hpp:110:30: required from ‘struct State<TicTacToeState, TicTacToeMove>’
tests/../examples/tic_tac_toe.cpp:69:32: required from here
/usr/include/c++/4.8/bits/stl_pair.h:102:11: error: ‘std::pair<_T1, _T2>::second’ has incomplete type
_T2 second; /// @c second is a copy of the second object
^
In file included from tests/test_tic_tac_toe.cpp:3:0:
tests/../examples/tic_tac_toe.cpp:69:8: error: forward declaration of ‘struct TicTacToeState’
struct TicTacToeState : public State<TicTacToeState, TicTacToeMove> {
^
In file included from /usr/include/c++/4.8/utility:70:0,
from /usr/include/boost/config/no_tr1/utility.hpp:21,
from /usr/include/boost/config/select_stdlib_config.hpp:37,
from /usr/include/boost/config.hpp:40,
from /usr/include/boost/functional/hash/hash_fwd.hpp:17,
from /usr/include/boost/functional/hash/hash.hpp:13,
from /usr/include/boost/functional/hash.hpp:6,
from tests/../examples/tic_tac_toe.cpp:1,
from tests/test_tic_tac_toe.cpp:3:
/usr/include/c++/4.8/bits/stl_pair.h: In instantiation of ‘constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U1 = long unsigned int&; _U2 = TicTacToeState&; <template-parameter-2-3> = void; _T1 = const long unsigned int; _T2 = TicTacToeState]’:
tests/../examples/../gtsa.hpp:640:57: required from ‘S* MonteCarloTreeSearch<S, M>::add_child(S*, M&) [with S = TicTacToeState; M = TicTacToeMove]’
tests/../examples/../gtsa.hpp:472:41: required from ‘S* MonteCarloTreeSearch<S, M>::tree_policy(S*, S*) [with S = TicTacToeState; M = TicTacToeMove]’
tests/../examples/../gtsa.hpp:453:44: required from ‘void MonteCarloTreeSearch<S, M>::monte_carlo_tree_search(S*) [with S = TicTacToeState; M = TicTacToeMove]’
tests/../examples/../gtsa.hpp:433:41: required from ‘M MonteCarloTreeSearch<S, M>::get_move(S*) [with S = TicTacToeState; M = TicTacToeMove]’
tests/test_tic_tac_toe.cpp:123:1: required from here
/usr/include/c++/4.8/bits/stl_pair.h:145:64: error: using invalid field ‘std::pair<_T1, _T2>::second’
: first(std::forward<_U1>(__x)), second(std::forward<_U2>(__y)) { }
^
我的理解是:
我要求創建一個struct TicTacToeState,它看起來什麼是基類,啊哈,它的模板,做工精細,它會嘗試使用S = TicTacToeState實例化狀態但失敗,因爲unordered_map<int, S>
需要已經爲映射值定義了類型,但未定義TicTacToeState。
將TicTacToeState置於前面不會有幫助,因爲那樣它將沒有國家聲明。
如果有人想對原始代碼有更廣泛的瞭解,State定義爲here。我第一次使用CRTP,也許我不需要它,它只是使代碼複雜化?我不知道,我還沒找到任何簡單的東西。
如何使它工作?
標準庫容器不能保證在不完整的類型下正常工作。嘗試使用'S *'作爲映射類型,它應該可以工作。 – Brian