Saturday, January 21, 2017

Including header file in .cpp causes nasty error

Leave a Comment

I have a header file called transaction_gen.h and a corresponding cpp file called transaction_gen.cpp.

Here is what I have in transaction_gen.h

#ifndef BITCOIN_TEST_GEN_TRANSACTION_GEN_H #define BITCOIN_TEST_GEN_TRANSACTION_GEN_H  #include <rapidcheck/gen/Arbitrary.h> #include <rapidcheck/Gen.h> #include "primitives/transaction.h"  #include "script/script.h" #include "amount.h" #include "test/gen/script_gen.h" #include "test/gen/crypto_gen.h"  namespace rc {    template<>   struct Arbitrary<COutPoint> {     static Gen<COutPoint> arbitrary() {        return gen::map(gen::tuple(gen::arbitrary<uint256>(), gen::arbitrary<uint32_t>()), [](std::tuple<uint256, uint32_t> outPointPrimitives) {           uint32_t nIn;            uint256 nHashIn;            std::tie(nHashIn, nIn) = outPointPrimitives;           return COutPoint(nHashIn, nIn);           });     };   };     template<>    struct Arbitrary<CTxIn> {      static Gen<CTxIn> arbitrary() {        return gen::map(gen::tuple(gen::arbitrary<COutPoint>(), gen::arbitrary<CScript>(), gen::arbitrary<uint32_t>()), [](std::tuple<COutPoint, CScript, uint32_t> txInPrimitives) {          COutPoint outpoint;          CScript script;         uint32_t sequence;          std::tie(outpoint,script,sequence) = txInPrimitives;          return CTxIn(outpoint,script,sequence);        });     };   };   /** Generates one or more inputs */    Gen<std::vector<CTxIn>> oneOrMoreInputs();     template<>   struct Arbitrary<CAmount> {     static Gen<CAmount> arbitrary() {       //why doesn't this generator call work? It seems to cause an infinite loop.        //return gen::arbitrary<int64_t>();       return gen::inRange(std::numeric_limits<int64_t>::min(),std::numeric_limits<int64_t>::max());     };   };     template<>   struct Arbitrary<CTxOut> {      static Gen<CTxOut> arbitrary() {        return gen::map(gen::tuple(gen::arbitrary<CAmount>(), gen::arbitrary<CScript>()), [](std::tuple<CAmount, CScript> txOutPrimitives) {         CAmount amount;           CScript script;         std::tie(amount,script) = txOutPrimitives;         return CTxOut(amount,script);       });     };   };  

and here is what I have in the corresponding cpp file

#include <rapidcheck/gen/Arbitrary.h> #include <rapidcheck/Gen.h>  #include "primitives/transaction.h"  #include "script/script.h" #include "amount.h"  #include "test/gen/transaction_gen.h"  namespace rc {     /** Generates one or more inputs */    Gen<std::vector<CTxIn>> oneOrMoreInputs() {     return gen::suchThat(gen::arbitrary<std::vector<CTxIn>>(), [](std::vector<CTxIn> vin) {       return vin.size() > 0;           });   }    /** Generates one or more outputs */    Gen<std::vector<CTxOut>> oneOrMoreOutputs() {      return gen::suchThat(gen::arbitrary<std::vector<CTxOut>>(), [](std::vector<CTxOut> vout) {       return vout.size() > 0;           });   }  } 

and this will compile fine when I build my program.

However, since I want to be using functionality located in transaction_gen.h I obviously want to include it in my program. However, when I include it I get a long nasty error message:

chris@chris-870Z5E-880Z5E-680Z5E:~/.../src/test$ make make -C .. bitcoin_test make[1]: Entering directory `/home/chris/dev/bitcoin/src'   CXX      test/test_test_bitcoin-transaction_properties.o   CXX      test/gen/test_test_bitcoin-transaction_gen.o In file included from ./test/gen/script_gen.h:6:0,                  from ./test/gen/transaction_gen.h:9,                  from test/gen/transaction_gen.cpp:8: ./test/gen/crypto_gen.h: In static member function ‘static rc::Gen<CKey> rc::Arbitrary<CKey>::arbitrary()’: ./test/gen/crypto_gen.h:19:8: error: no matching function for call to ‘map(rc::Arbitrary<CKey>::arbitrary()::<lambda(int)>)’        });         ^ In file included from /usr/local/include/rapidcheck/Gen.h:74:0,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/Gen.hpp:15:54: note: candidate: template<class T, class Mapper> rc::Gen<typename std::decay<typename std::result_of<Mapper(T)>::type>::type> rc::gen::map(rc::Gen<T>, Mapper&&)  Gen<Decay<typename std::result_of<Mapper(T)>::type>> map(Gen<T> gen,                                                       ^ /usr/local/include/rapidcheck/Gen.hpp:15:54: note:   template argument deduction/substitution failed: In file included from ./test/gen/script_gen.h:6:0,                  from ./test/gen/transaction_gen.h:9,                  from test/gen/transaction_gen.cpp:8: ./test/gen/crypto_gen.h:19:8: note:   candidate expects 2 arguments, 1 provided        });         ^ ./test/gen/crypto_gen.h: In static member function ‘static rc::Gen<std::vector<unsigned char, secure_allocator<unsigned char> > > rc::Arbitrary<std::vector<unsigned char, secure_allocator<unsigned char> > >::arbitrary()’: ./test/gen/crypto_gen.h:29:8: error: no matching function for call to ‘map(rc::Arbitrary<std::vector<unsigned char, secure_allocator<unsigned char> > >::arbitrary()::<lambda(CKey)>)’        });         ^ In file included from /usr/local/include/rapidcheck/Gen.h:74:0,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/Gen.hpp:15:54: note: candidate: template<class T, class Mapper> rc::Gen<typename std::decay<typename std::result_of<Mapper(T)>::type>::type> rc::gen::map(rc::Gen<T>, Mapper&&)  Gen<Decay<typename std::result_of<Mapper(T)>::type>> map(Gen<T> gen,                                                       ^ /usr/local/include/rapidcheck/Gen.hpp:15:54: note:   template argument deduction/substitution failed: In file included from ./test/gen/script_gen.h:6:0,                  from ./test/gen/transaction_gen.h:9,                  from test/gen/transaction_gen.cpp:8: ./test/gen/crypto_gen.h:29:8: note:   candidate expects 2 arguments, 1 provided        });         ^ ./test/gen/crypto_gen.h: In static member function ‘static rc::Gen<CPubKey> rc::Arbitrary<CPubKey>::arbitrary()’: ./test/gen/crypto_gen.h:39:8: error: no matching function for call to ‘map(rc::Arbitrary<CPubKey>::arbitrary()::<lambda(CKey)>)’        });         ^ In file included from /usr/local/include/rapidcheck/Gen.h:74:0,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/Gen.hpp:15:54: note: candidate: template<class T, class Mapper> rc::Gen<typename std::decay<typename std::result_of<Mapper(T)>::type>::type> rc::gen::map(rc::Gen<T>, Mapper&&)  Gen<Decay<typename std::result_of<Mapper(T)>::type>> map(Gen<T> gen,                                                       ^ /usr/local/include/rapidcheck/Gen.hpp:15:54: note:   template argument deduction/substitution failed: In file included from ./test/gen/script_gen.h:6:0,                  from ./test/gen/transaction_gen.h:9,                  from test/gen/transaction_gen.cpp:8: ./test/gen/crypto_gen.h:39:8: note:   candidate expects 2 arguments, 1 provided        });         ^ ./test/gen/crypto_gen.h: In static member function ‘static rc::Gen<uint256> rc::Arbitrary<uint256>::arbitrary()’: ./test/gen/crypto_gen.h:49:8: error: no matching function for call to ‘map(rc::Arbitrary<uint256>::arbitrary()::<lambda(int)>)’        });          ^ In file included from /usr/local/include/rapidcheck/Gen.h:74:0,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/Gen.hpp:15:54: note: candidate: template<class T, class Mapper> rc::Gen<typename std::decay<typename std::result_of<Mapper(T)>::type>::type> rc::gen::map(rc::Gen<T>, Mapper&&)  Gen<Decay<typename std::result_of<Mapper(T)>::type>> map(Gen<T> gen,                                                       ^ /usr/local/include/rapidcheck/Gen.hpp:15:54: note:   template argument deduction/substitution failed: In file included from ./test/gen/script_gen.h:6:0,                  from ./test/gen/transaction_gen.h:9,                  from test/gen/transaction_gen.cpp:8: ./test/gen/crypto_gen.h:49:8: note:   candidate expects 2 arguments, 1 provided        });          ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp: In instantiation of ‘struct rc::Arbitrary<std::vector<unsigned char> >’: /usr/local/include/rapidcheck/gen/Arbitrary.h:17:33:   required by substitution of ‘template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary() [with T = std::vector<unsigned char>]’ ./test/gen/script_gen.h:13:66:   required from here /usr/local/include/rapidcheck/gen/Arbitrary.hpp:22:62: error: incomplete type ‘rc::gen::detail::DefaultArbitrary<std::vector<unsigned char> >’ used in nested name specifier    static decltype(gen::detail::DefaultArbitrary<T>::arbitrary()) arbitrary() {                                                               ^ In file included from ./test/gen/transaction_gen.h:9:0,                  from test/gen/transaction_gen.cpp:8: ./test/gen/script_gen.h: In static member function ‘static rc::Gen<CScript> rc::Arbitrary<CScript>::arbitrary()’: ./test/gen/script_gen.h:13:66: error: no matching function for call to ‘arbitrary()’        return gen::map(gen::arbitrary<std::vector<unsigned char>>(), [](std::vector<unsigned char> script) {                                                                   ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note: candidate: template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary()  decltype(Arbitrary<T>::arbitrary()) arbitrary() {                                      ^ /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note:   substitution of deduced template arguments resulted in errors seen above In file included from test/gen/transaction_gen.cpp:8:0: ./test/gen/transaction_gen.h: In static member function ‘static rc::Gen<COutPoint> rc::Arbitrary<COutPoint>::arbitrary()’: ./test/gen/transaction_gen.h:17:23: error: ‘tuple’ is not a member of ‘rc::gen’        return gen::map(gen::tuple(gen::arbitrary<uint256>(), gen::arbitrary<uint32_t>()), [](std::tuple<uint256, uint32_t> outPointPrimitives) {                        ^ ./test/gen/transaction_gen.h:17:23: note: suggested alternative: In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0,                  from /usr/include/c++/5/memory:62,                  from /usr/local/include/rapidcheck/Seq.h:4,                  from /usr/local/include/rapidcheck/Shrinkable.h:3,                  from /usr/local/include/rapidcheck/Gen.h:4,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/include/c++/5/bits/stl_pair.h:83:11: note:   ‘std::tuple’      class tuple;            ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp: In instantiation of ‘struct rc::Arbitrary<unsigned int>’: /usr/local/include/rapidcheck/gen/Arbitrary.h:17:33:   required by substitution of ‘template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary() [with T = unsigned int]’ ./test/gen/transaction_gen.h:17:86:   required from here /usr/local/include/rapidcheck/gen/Arbitrary.hpp:22:62: error: incomplete type ‘rc::gen::detail::DefaultArbitrary<unsigned int>’ used in nested name specifier    static decltype(gen::detail::DefaultArbitrary<T>::arbitrary()) arbitrary() {                                                               ^ In file included from test/gen/transaction_gen.cpp:8:0: ./test/gen/transaction_gen.h:17:86: error: no matching function for call to ‘arbitrary()’        return gen::map(gen::tuple(gen::arbitrary<uint256>(), gen::arbitrary<uint32_t>()), [](std::tuple<uint256, uint32_t> outPointPrimitives) {                                                                                       ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note: candidate: template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary()  decltype(Arbitrary<T>::arbitrary()) arbitrary() {                                      ^ /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note:   substitution of deduced template arguments resulted in errors seen above In file included from test/gen/transaction_gen.cpp:8:0: ./test/gen/transaction_gen.h: In static member function ‘static rc::Gen<CTxIn> rc::Arbitrary<CTxIn>::arbitrary()’: ./test/gen/transaction_gen.h:30:23: error: ‘tuple’ is not a member of ‘rc::gen’        return gen::map(gen::tuple(gen::arbitrary<COutPoint>(), gen::arbitrary<CScript>(), gen::arbitrary<uint32_t>()), [](std::tuple<COutPoint, CScript, uint32_t> txInPrimitives) {                         ^ ./test/gen/transaction_gen.h:30:23: note: suggested alternative: In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0,                  from /usr/include/c++/5/memory:62,                  from /usr/local/include/rapidcheck/Seq.h:4,                  from /usr/local/include/rapidcheck/Shrinkable.h:3,                  from /usr/local/include/rapidcheck/Gen.h:4,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/include/c++/5/bits/stl_pair.h:83:11: note:   ‘std::tuple’      class tuple;            ^ In file included from test/gen/transaction_gen.cpp:8:0: ./test/gen/transaction_gen.h:30:115: error: no matching function for call to ‘arbitrary()’        return gen::map(gen::tuple(gen::arbitrary<COutPoint>(), gen::arbitrary<CScript>(), gen::arbitrary<uint32_t>()), [](std::tuple<COutPoint, CScript, uint32_t> txInPrimitives) {                                                                                                                     ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note: candidate: template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary()  decltype(Arbitrary<T>::arbitrary()) arbitrary() {                                      ^ /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note:   template argument deduction/substitution failed: In file included from test/gen/transaction_gen.cpp:1:0: /usr/local/include/rapidcheck/gen/Arbitrary.h: In substitution of ‘template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary() [with T = unsigned int]’: ./test/gen/transaction_gen.h:30:115:   required from here /usr/local/include/rapidcheck/gen/Arbitrary.h:17:33: error: ‘arbitrary’ is not a member of ‘rc::Arbitrary<unsigned int>’  decltype(Arbitrary<T>::arbitrary()) arbitrary();                                  ^ In file included from test/gen/transaction_gen.cpp:8:0: ./test/gen/transaction_gen.h: In static member function ‘static rc::Gen<long int> rc::Arbitrary<long int>::arbitrary()’: ./test/gen/transaction_gen.h:48:14: error: ‘inRange’ is not a member of ‘rc::gen’        return gen::inRange(std::numeric_limits<int64_t>::min(),std::numeric_limits<int64_t>::max());               ^ ./test/gen/transaction_gen.h: In static member function ‘static rc::Gen<CTxOut> rc::Arbitrary<CTxOut>::arbitrary()’: ./test/gen/transaction_gen.h:55:23: error: ‘tuple’ is not a member of ‘rc::gen’        return gen::map(gen::tuple(gen::arbitrary<CAmount>(), gen::arbitrary<CScript>()), [](std::tuple<CAmount, CScript> txOutPrimitives) {                        ^ ./test/gen/transaction_gen.h:55:23: note: suggested alternative: In file included from /usr/include/c++/5/bits/stl_algobase.h:64:0,                  from /usr/include/c++/5/memory:62,                  from /usr/local/include/rapidcheck/Seq.h:4,                  from /usr/local/include/rapidcheck/Shrinkable.h:3,                  from /usr/local/include/rapidcheck/Gen.h:4,                  from /usr/local/include/rapidcheck/gen/Arbitrary.h:3,                  from test/gen/transaction_gen.cpp:1: /usr/include/c++/5/bits/stl_pair.h:83:11: note:   ‘std::tuple’      class tuple;            ^ test/gen/transaction_gen.cpp: In function ‘rc::Gen<std::vector<CTxIn> > rc::oneOrMoreInputs()’: test/gen/transaction_gen.cpp:14:12: error: ‘suchThat’ is not a member of ‘rc::gen’      return gen::suchThat(gen::arbitrary<std::vector<CTxIn>>(), [](std::vector<CTxIn> vin) {             ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp: In instantiation of ‘struct rc::Arbitrary<std::vector<CTxIn> >’: /usr/local/include/rapidcheck/gen/Arbitrary.h:17:33:   required by substitution of ‘template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary() [with T = std::vector<CTxIn>]’ test/gen/transaction_gen.cpp:14:61:   required from here /usr/local/include/rapidcheck/gen/Arbitrary.hpp:22:62: error: incomplete type ‘rc::gen::detail::DefaultArbitrary<std::vector<CTxIn> >’ used in nested name specifier    static decltype(gen::detail::DefaultArbitrary<T>::arbitrary()) arbitrary() {                                                               ^ test/gen/transaction_gen.cpp:14:61: error: no matching function for call to ‘arbitrary()’      return gen::suchThat(gen::arbitrary<std::vector<CTxIn>>(), [](std::vector<CTxIn> vin) {                                                              ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note: candidate: template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary()  decltype(Arbitrary<T>::arbitrary()) arbitrary() {                                      ^ /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note:   substitution of deduced template arguments resulted in errors seen above test/gen/transaction_gen.cpp: In function ‘rc::Gen<std::vector<CTxOut> > rc::oneOrMoreOutputs()’: test/gen/transaction_gen.cpp:21:12: error: ‘suchThat’ is not a member of ‘rc::gen’      return gen::suchThat(gen::arbitrary<std::vector<CTxOut>>(), [](std::vector<CTxOut> vout) {             ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp: In instantiation of ‘struct rc::Arbitrary<std::vector<CTxOut> >’: /usr/local/include/rapidcheck/gen/Arbitrary.h:17:33:   required by substitution of ‘template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary() [with T = std::vector<CTxOut>]’ test/gen/transaction_gen.cpp:21:62:   required from here /usr/local/include/rapidcheck/gen/Arbitrary.hpp:22:62: error: incomplete type ‘rc::gen::detail::DefaultArbitrary<std::vector<CTxOut> >’ used in nested name specifier    static decltype(gen::detail::DefaultArbitrary<T>::arbitrary()) arbitrary() {                                                               ^ test/gen/transaction_gen.cpp:21:62: error: no matching function for call to ‘arbitrary()’      return gen::suchThat(gen::arbitrary<std::vector<CTxOut>>(), [](std::vector<CTxOut> vout) {                                                               ^ In file included from /usr/local/include/rapidcheck/gen/Arbitrary.h:22:0,                  from test/gen/transaction_gen.cpp:1: /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note: candidate: template<class T> decltype (rc::Arbitrary<T>::arbitrary()) rc::gen::arbitrary()  decltype(Arbitrary<T>::arbitrary()) arbitrary() {                                      ^ /usr/local/include/rapidcheck/gen/Arbitrary.hpp:13:37: note:   substitution of deduced template arguments resulted in errors seen above make[1]: *** [test/gen/test_test_bitcoin-transaction_gen.o] Error 1 make[1]: Leaving directory `/home/chris/dev/bitcoin/src' make: *** [all] Error 2 

and I'm not really sure why this is happening. It almost seems like when I include transaction_gen.h it erases all other header files I had included, this the problems like

In file included from ./test/gen/script_gen.h:6:0,                  from ./test/gen/transaction_gen.h:9,                  from test/gen/transaction_gen.cpp:8: ./test/gen/crypto_gen.h: In static member function ‘static rc::Gen<CKey> rc::Arbitrary<CKey>::arbitrary()’: ./test/gen/crypto_gen.h:19:8: error: no matching function for call to ‘map(rc::Arbitrary<CKey>::arbitrary()::<lambda(int)>)’        }); 

because this obviously is included properly when I exclude transaction_gen.h. Where am I going wrong here? I feel like this is a pretty simple fix but I've spent a couple hours on it now to avail :/

EDIT: I've pushed this up to github

Here is transaction_gen.h

Here is transaction_gen.cpp

3 Answers

Answers 1

Your transaction_gen.h is missing a #endif at the end of the file.

Answers 2

Try remove these lines from transaction_gen.cpp:

#include <rapidcheck/gen/Arbitrary.h> #include <rapidcheck/Gen.h>  #include "primitives/transaction.h"  #include "script/script.h" #include "amount.h" 

Keep this #include line only:

#include "test/gen/transaction_gen.h" 

Answers 3

Include these in your cpp file also

#include "test/gen/script_gen.h" #include "test/gen/crypto_gen.h" 
If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment