在模块中使用 constexpr 和 string_view
Using constexpr and string_view in module
现代 C++ 提供 constexpr
和 std::string_view
作为字符串文字的方便替代方法。但是,我无法 link 到模块中的“constexpr std::string_view
”。相比之下,我可以在模块中使用 string_view
(not constexpr
) 以及“constexpr std::string_view
” 模块外部。此外,模块中 constexpr
的其他用途不会出现此问题,例如整数。
下面是重现错误的最少代码:
模块接口单元(my_string.cpp):
export module my_string;
import <string_view>;
export namespace my_string {
struct MyString {
static std::string_view string_at_runtime;
static constexpr std::string_view string_at_compilation{"Hello World at compilation (inside module)"};
static constexpr int number_at_compilation{1};
};
}
模块实现单元(my_string_impl.cpp):
module;
module my_string;
namespace my_string {
std::string_view MyString::string_at_runtime = "Hello World at runtime";
}
hello_world.cpp:
import <iostream>;
import <string_view>;
import my_string;
static constexpr std::string_view hello_world{"Hello World at compilation (outside module)"};
int main(){
std::cout << hello_world << std::endl;
std::cout << my_string::MyString::string_at_runtime << std::endl;
std::cout << my_string::MyString::number_at_compilation << std::endl;
std::cout << my_string::MyString::string_at_compilation << std::endl; //<-- ERROR is here
}
编译并尝试 link(在 Linux 上使用 gcc 11.2.0 运行):
g++ -c -fmodules-ts -std=c++20 -xc++-system-header iostream string_view
g++ -c my_string.cpp -fmodules-ts -std=c++20
g++ -c my_string_impl.cpp -fmodules-ts -std=c++20
g++ -c hello_world.cpp -fmodules-ts -std=c++20
g++ -o main my_string.o my_string_impl.o hello_world.o -fmodules-ts -std=c++20
只有最后一条指令(linking)导致错误:
g++ -o main my_string.o my_string_impl.o hello_world.o -fmodules-ts -std=c++20
/usr/bin/ld: hello_world.o: in function `main':
hello_world.cpp:(.text+0x97): undefined reference to `my_string::MyString::string_at_compilation'
collect2: error: ld returned 1 exit status
除了搜索相关问题的答案(例如constexpr
in modules and constexpr
and namespace
s) I have reread the GCC Wiki。我还没有用其他编译器(例如clang,msvc)尝试过这段代码。
此错误是我的代码失败还是 gcc 中尚未实现的功能?
我找到了解决方案:添加 getter 方法。
在模块接口单元(my_string.cpp)中添加:
static std::string_view GetStringAtCompilation();
在模块实现单元(my_string_impl.cpp)中添加:
std::string_view MyString::GetStringAtCompilation(){
return string_at_compilation;
}
现在“main”函数中的以下行(参见有问题的 hello_world.cpp)编译、链接和执行没有错误:
std::cout << my_string::MyString::GetStringAtCompilation() << std::endl;
我相信在这个关于
的答案中给出了没有 getter 方法的原始尝试不起作用的原因
现代 C++ 提供 constexpr
和 std::string_view
作为字符串文字的方便替代方法。但是,我无法 link 到模块中的“constexpr std::string_view
”。相比之下,我可以在模块中使用 string_view
(not constexpr
) 以及“constexpr std::string_view
” 模块外部。此外,模块中 constexpr
的其他用途不会出现此问题,例如整数。
下面是重现错误的最少代码:
模块接口单元(my_string.cpp):
export module my_string;
import <string_view>;
export namespace my_string {
struct MyString {
static std::string_view string_at_runtime;
static constexpr std::string_view string_at_compilation{"Hello World at compilation (inside module)"};
static constexpr int number_at_compilation{1};
};
}
模块实现单元(my_string_impl.cpp):
module;
module my_string;
namespace my_string {
std::string_view MyString::string_at_runtime = "Hello World at runtime";
}
hello_world.cpp:
import <iostream>;
import <string_view>;
import my_string;
static constexpr std::string_view hello_world{"Hello World at compilation (outside module)"};
int main(){
std::cout << hello_world << std::endl;
std::cout << my_string::MyString::string_at_runtime << std::endl;
std::cout << my_string::MyString::number_at_compilation << std::endl;
std::cout << my_string::MyString::string_at_compilation << std::endl; //<-- ERROR is here
}
编译并尝试 link(在 Linux 上使用 gcc 11.2.0 运行):
g++ -c -fmodules-ts -std=c++20 -xc++-system-header iostream string_view
g++ -c my_string.cpp -fmodules-ts -std=c++20
g++ -c my_string_impl.cpp -fmodules-ts -std=c++20
g++ -c hello_world.cpp -fmodules-ts -std=c++20
g++ -o main my_string.o my_string_impl.o hello_world.o -fmodules-ts -std=c++20
只有最后一条指令(linking)导致错误:
g++ -o main my_string.o my_string_impl.o hello_world.o -fmodules-ts -std=c++20
/usr/bin/ld: hello_world.o: in function `main':
hello_world.cpp:(.text+0x97): undefined reference to `my_string::MyString::string_at_compilation'
collect2: error: ld returned 1 exit status
除了搜索相关问题的答案(例如constexpr
in modules and constexpr
and namespace
s) I have reread the GCC Wiki。我还没有用其他编译器(例如clang,msvc)尝试过这段代码。
此错误是我的代码失败还是 gcc 中尚未实现的功能?
我找到了解决方案:添加 getter 方法。
在模块接口单元(my_string.cpp)中添加:
static std::string_view GetStringAtCompilation();
在模块实现单元(my_string_impl.cpp)中添加:
std::string_view MyString::GetStringAtCompilation(){
return string_at_compilation;
}
现在“main”函数中的以下行(参见有问题的 hello_world.cpp)编译、链接和执行没有错误:
std::cout << my_string::MyString::GetStringAtCompilation() << std::endl;
我相信在这个关于