如何在 header 中公开引用变量?
How to expose a reference variable in a header?
为了方便 (MVCE),我正在尝试在 boost::bimap
的一侧创建一个引用变量 cParamIDsByAge
:
尝试 #1
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;
^~~~~~~~~~~~~~
尝试 #2
然后我尝试直接在header中定义引用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
尝试 #3
我没有初始化 header 中的引用:
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;
编译器抱怨 header 文件:
error: declaration of ‘const auto& cParamIDsByAge’ has no initializer
错误消息 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
的类型。您不能在 extern
声明中使用 auto
,因为没有可从中推断出的初始化程序。
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 都拒绝它。
将 header 中的行更改为以下内容:
// REMOVE: extern auto &cParamIDsByAge = cParamIDs.left;
extern const decltype(cParamIDs.left) &cParamIDsByAge;
这是向前正确声明引用变量。其余的应该按原样工作。
解决方案 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;
解决方案 2
使用函数代替变量:
code.h
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
inline auto& cParamIDsByAge() { return cParamIDs.left; }
为了方便 (MVCE),我正在尝试在 boost::bimap
的一侧创建一个引用变量 cParamIDsByAge
:
尝试 #1
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;
^~~~~~~~~~~~~~
尝试 #2
然后我尝试直接在header中定义引用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
尝试 #3
我没有初始化 header 中的引用:
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;
编译器抱怨 header 文件:
error: declaration of ‘const auto& cParamIDsByAge’ has no initializer
错误消息 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
的类型。您不能在 extern
声明中使用 auto
,因为没有可从中推断出的初始化程序。
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 都拒绝它。
将 header 中的行更改为以下内容:
// REMOVE: extern auto &cParamIDsByAge = cParamIDs.left;
extern const decltype(cParamIDs.left) &cParamIDsByAge;
这是向前正确声明引用变量。其余的应该按原样工作。
解决方案 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;
解决方案 2
使用函数代替变量:
code.h
#include <boost/bimap.hpp>
typedef boost::bimap <int, int> ParamIDs;
extern const ParamIDs cParamIDs;
inline auto& cParamIDsByAge() { return cParamIDs.left; }