c++ - Visual Studio 2013: linker errors with custom enumerations? -


i'm using following code, written james mcnellis, simplify declaring more-functional c++2011 enums:

#pragma once #include <stdexcept> #include <boost/preprocessor.hpp> #include <vector>  // internal helper provide partial specialization checked_enum_cast template <typename target, typename source> struct checked_enum_cast_impl;  // exception thrown checked_enum_cast on cast failure struct invalid_enum_cast : std::out_of_range {     invalid_enum_cast(const char* s)         : std::out_of_range(s) { } };  // checked cast function template <typename target, typename source> target checked_enum_cast(source s) {     return checked_enum_cast_impl<target, source>::do_cast(s); }  // internal helper declare case labels in checked cast function #define x_define_safe_cast_case(r, data, elem) case elem:  // how this? question asked on stackoverflow 11/30/14 -- check again soon. #define x_add_to_toret(r, data, elem) toret.push_back(elem)  // defines enumeration checked cast function. //   name name of enumeration defined //   enumerators preprocessing sequence of enumerators defined. #define denum(name, enumerators)                           \ enum name                                                              \ {                                                                      \     boost_pp_seq_enum(enumerators)                                     \ };                                                                     \                                                                        \ template <typename source>                                             \ struct checked_enum_cast_impl<name, source>                            \ {                                                                      \     static name cast(source s)                                      \     {                                                                  \         switch (s)                                                     \         {                                                              \         boost_pp_seq_for_each(x_define_safe_cast_case, 0, enumerators) \             return static_cast<name>(s);                               \         default:                                                       \             throw invalid_enum_cast(boost_pp_stringize(name));         \         }                                                              \         return name();                                                 \     }                                                                  \ };                                                                  \ std::vector<name> membersof(name anyitem) {     \     return {boost_pp_seq_enum(enumerators)}; \ };  

when declare enumeration (the syntax denum(system_states, (loading)(running)(finished));, example), membersof() generates linker error whenever file containing declaration linked multiple objects -- even, example, main.obj , someclass.obj. specific error texts:

1>main.obj : error lnk2005: "class std::vector<enum system_states,class std::allocator<enum system_states> > __cdecl membersof(enum system_states)" (?membersof@@ya?av?$vector@w4system_states@@v?$allocator@w4system_states@@@std@@@std@@w4system_states@@@z) defined in controller.obj 1>userinputprocessor.obj : error lnk2005: "class std::vector<enum system_states,class std::allocator<enum system_states> > __cdecl membersof(enum system_states)" (?membersof@@ya?av?$vector@w4system_states@@v?$allocator@w4system_states@@@std@@@std@@w4system_states@@@z) defined in controller.obj 1>c:\users\username\documents\membersof investigation\debug\membersof investigation.exe : fatal error lnk1169: 1 or more multiply defined symbols found 

i know worked couple of months ago, before installed sfml on system, don't think it's cause; reproduced problem in testbed project i'm not linking sfml.

other things declared in header uses above enums, , other uses of boost, work properly.

you should mark memberof inline. other option mark static (as mentioned in comment @simon). link, potentially create copy of memberof in each compilation unit uses function. declaring memberof inline instead should force emitted functions merged 1 linker.

the reason should because believe behavior implementation-defined. in practice, believe above true major implementations, including msvc.


Comments

Popular posts from this blog

python - pip install -U PySide error -

arrays - C++ error: a brace-enclosed initializer is not allowed here before ‘{’ token -

cytoscape.js - How to add nodes to Dagre layout with Cytoscape -