为了方便起见,我正试图在cParamIDsByAge
的一侧创建引用变量boost::bimap
:
code.h
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
extern auto &cParamIDsByAge = cParamIDs.left;
code.cpp
#include "code.h"
// In my code this inits the variable with some data via a function.
const ParamIDs cParamIDs {};
auto &cParamIDsByAge = cParamIDs.left;
编译器抱怨:
code.h:5:14: warning: ‘cParamIDsByAge’ initialized and declared ‘extern’
extern auto &cParamIDsByAge = cParamIDs.left;
^~~~~~~~~~~~~~
code.cpp:4:7: error: conflicting declaration ‘auto& cParamIDsByAge’
auto &cParamIDsByAge = cParamIDs.left;
^~~~~~~~~~~~~~
In file included from code.cpp:1:0:
code.h:5:14: note: previous declaration as ‘const boost::bimaps::views::map_view<boost::bimaps::relation::member_at::left, boost::bimaps::detail::bimap_core<int, int, mpl_::na, mpl_::na, mpl_::na> >& cParamIDsByAge’
extern auto &cParamIDsByAge = cParamIDs.left;
^~~~~~~~~~~~~~
然后我尝试直接在标题中定义引用cParamIDsByAge
:
code.h
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
auto &cParamIDsByAge = cParamIDs.left;
code.cpp
#include "code.h"
const ParamIDs cParamIDs {};
但是抱怨说:
error: multiple definitions of cParamIDsByAge
我没有初始化标题中的引用:
code.h
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
extern const auto &cParamIDsByAge;
code.cpp
#include "code.h"
const ParamIDs cParamIDs {};
auto &cParamIDsByAge = cParamIDs.left;
编译器抱怨头文件:
error: declaration of ‘const auto& cParamIDsByAge’ has no initializer
答案 0 :(得分:4)
错误消息code.h:5:14: warning: ‘cParamIDsByAge’ initialized and declared ‘extern’
非常简单:在C ++中,声明为extern
的变量可能没有初始值设定项。 (换句话说,extern
可能只出现在声明中,而不是定义中。
示例用法可能是:
extern int &foo;
// ... cpp file
int bar;
int &foo = bar;
要在您的代码中执行此操作,还有一个问题是您需要将int
替换为boost::bimap::left
类型。您无法在auto
声明中使用extern
,因为没有可以推断出的初始值设定项。
boost::bimap
碰巧将此定义为typedef,因此解决方案很简单:
extern ParamIDs::left_map const &x;
// ... in cpp
const ParamIDs c{};
ParamIDs::left_map const &x = c.left;
如果该typedef不存在,那么您仍然可以使用declval
和decltype
来执行此操作。
注1:我认为标准不清楚auto const &x = c.left;
是否适用于此,但gcc和clang都拒绝它。
答案 1 :(得分:2)
将标题中的行更改为以下内容:
// REMOVE: extern auto &cParamIDsByAge = cParamIDs.left;
extern const decltype(cParamIDs.left) &cParamIDsByAge;
这是正确地声明参考变量。其余的应该按原样运作。
答案 2 :(得分:1)
在标题文件中,声明cParamIDsByAge
的类型而不使用auto并且不要初始化它:
<强> code.h 强>
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
extern const decltype(cParamIDs.left)& cParamIDsByAge;
// or
extern decltype((cParamIDs.left)) cParamIDsByAge;
// or
extern const ParamIDs::left_map& cParamIDsByAge;
<强> code.cpp 强>
#include "code.h"
const ParamIDs cParamIDs {};
auto &cParamIDsByAge = cParamIDs.left;
使用函数而不是变量:
<强> code.h 强>
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
inline auto& cParamIDsByAge() { return cParamIDs.left; }