不同翻译单元中的内联静态变量具有不同的值(c++17)
inline static variable in different translation units has different values(c++17)
我想实现一个包含全局变量的源文件,我想通过 inline static
来实现。我可以在翻译单元的上下文中更改变量(例如 i
),但是当我在该翻译单元外部调用该变量时,调用者的结果将保持不变。就像每个单元都有一个副本。请参阅以下示例:
header.h
#ifndef UNTITLED1_TEST_H
#define UNTITLED1_TEST_H
namespace t {
inline static int i{0};
void inc() ;
void print_i() ;
}
#endif //UNTITLED1_TEST_H
header.cpp
#include "header.h"
void t::inc() {
t::i++;
}
void t::print_i() {
std::cout << t::i << std::endl;
}
那么让我们看看程序是如何执行的:
main.cpp
#include "header.h"
int main() {
t::inc();
std::cout << t::i << std::endl; // -> output is: 0
t::print_i(); // -> output is : 1
}
如您所见,变量i
在不同的翻译单元中有不同的值,如何解决?我不能使用 类 或其他任何东西,因为客户需要这种格式的代码。
注意
我可以做下面的事情,但这不是主要问题,我想要一个全局变量:
t::i++; //instead of t::inc();
std::cout << t::i << std::endl; // it's okay now, but it's not what I wanted
或者,我可以使用 inline
而不是 inline static
。它似乎有效,但我的导师说我应该改用 inline static
。
static
变量(如您的示例)具有 内部链接 。有两种方法可以实现您想要的效果,如下所示。另请注意,static
关键字还有其他含义。
方法一:C++17
在 C++17 中,我们可以使用 inline
关键字,如下所示:
header.h
#ifndef UNTITLED1_TEST_H
#define UNTITLED1_TEST_H
namespace t {
inline int i{0};//note the keyword inline here and initializer while keyword static has been removed
void inc() ;
void print_i() ;
}
#endif
header.cpp
#include "header.h"
#include <iostream>
//No need for initilaizing t::i here
void t::inc() {
t::i++;
}
void t::print_i() {
std::cout << t::i << std::endl;
}
main.cpp
#include <iostream>
#include"header.h"
int main() {
t::inc();
std::cout << t::i << std::endl; // -> output is: 1
t::print_i(); // -> output is : 1
}
方法1的输出可见here.
方法二:Pre-C++17
这里我们使用extern
关键字,这样变量就可以有外部链接.
main.cpp
#include <iostream>
#include"header.h"
int main() {
t::inc();
std::cout << t::i << std::endl; // -> output is: 1
t::print_i(); // -> output is : 1
}
header.h
#ifndef UNTITLED1_TEST_H
#define UNTITLED1_TEST_H
namespace t {
extern int i;//note the keyword extern and no initializer here
void inc() ;
void print_i() ;
}
#endif
注意我删除了添加的 static
和 inline
关键字,并添加了 extern
关键字。现在该变量具有 外部链接 。另外,请注意 t::i
的初始化是在下面给出的 header.cpp 中完成的。
header.cpp
#include "header.h"
#include <iostream>
int t::i{}; //initialize t::i
void t::inc() {
t::i++;
}
void t::print_i() {
std::cout << t::i << std::endl;
}
以上程序的输出为:Demo
1
1
此外,请注意关键字 static
还有其他含义。但是我已经根据给定的示例代码片段进行了回答。
关键字 static
有许多不同的含义,具体取决于上下文。您在错误的上下文中使用了 static
。你可以这样做
namespace t {
inline int i{0}; // no static
}
或这个
class t {
public:
inline static int i{0};
}:
所有这些都应该在头文件中,.cpp 文件中没有其他定义,也没有 extern
关键字。这些东西在 C++14 或更早版本中是必需的,但在 C++-17 或更高版本中不需要。
我想实现一个包含全局变量的源文件,我想通过 inline static
来实现。我可以在翻译单元的上下文中更改变量(例如 i
),但是当我在该翻译单元外部调用该变量时,调用者的结果将保持不变。就像每个单元都有一个副本。请参阅以下示例:
header.h
#ifndef UNTITLED1_TEST_H
#define UNTITLED1_TEST_H
namespace t {
inline static int i{0};
void inc() ;
void print_i() ;
}
#endif //UNTITLED1_TEST_H
header.cpp
#include "header.h"
void t::inc() {
t::i++;
}
void t::print_i() {
std::cout << t::i << std::endl;
}
那么让我们看看程序是如何执行的:
main.cpp
#include "header.h"
int main() {
t::inc();
std::cout << t::i << std::endl; // -> output is: 0
t::print_i(); // -> output is : 1
}
如您所见,变量i
在不同的翻译单元中有不同的值,如何解决?我不能使用 类 或其他任何东西,因为客户需要这种格式的代码。
注意
我可以做下面的事情,但这不是主要问题,我想要一个全局变量:
t::i++; //instead of t::inc();
std::cout << t::i << std::endl; // it's okay now, but it's not what I wanted
或者,我可以使用 inline
而不是 inline static
。它似乎有效,但我的导师说我应该改用 inline static
。
static
变量(如您的示例)具有 内部链接 。有两种方法可以实现您想要的效果,如下所示。另请注意,static
关键字还有其他含义。
方法一:C++17
在 C++17 中,我们可以使用 inline
关键字,如下所示:
header.h
#ifndef UNTITLED1_TEST_H
#define UNTITLED1_TEST_H
namespace t {
inline int i{0};//note the keyword inline here and initializer while keyword static has been removed
void inc() ;
void print_i() ;
}
#endif
header.cpp
#include "header.h"
#include <iostream>
//No need for initilaizing t::i here
void t::inc() {
t::i++;
}
void t::print_i() {
std::cout << t::i << std::endl;
}
main.cpp
#include <iostream>
#include"header.h"
int main() {
t::inc();
std::cout << t::i << std::endl; // -> output is: 1
t::print_i(); // -> output is : 1
}
方法1的输出可见here.
方法二:Pre-C++17
这里我们使用extern
关键字,这样变量就可以有外部链接.
main.cpp
#include <iostream>
#include"header.h"
int main() {
t::inc();
std::cout << t::i << std::endl; // -> output is: 1
t::print_i(); // -> output is : 1
}
header.h
#ifndef UNTITLED1_TEST_H
#define UNTITLED1_TEST_H
namespace t {
extern int i;//note the keyword extern and no initializer here
void inc() ;
void print_i() ;
}
#endif
注意我删除了添加的 static
和 inline
关键字,并添加了 extern
关键字。现在该变量具有 外部链接 。另外,请注意 t::i
的初始化是在下面给出的 header.cpp 中完成的。
header.cpp
#include "header.h"
#include <iostream>
int t::i{}; //initialize t::i
void t::inc() {
t::i++;
}
void t::print_i() {
std::cout << t::i << std::endl;
}
以上程序的输出为:Demo
1
1
此外,请注意关键字 static
还有其他含义。但是我已经根据给定的示例代码片段进行了回答。
关键字 static
有许多不同的含义,具体取决于上下文。您在错误的上下文中使用了 static
。你可以这样做
namespace t {
inline int i{0}; // no static
}
或这个
class t {
public:
inline static int i{0};
}:
所有这些都应该在头文件中,.cpp 文件中没有其他定义,也没有 extern
关键字。这些东西在 C++14 或更早版本中是必需的,但在 C++-17 或更高版本中不需要。