在模块中使用 constexpr 和 string_view

Using constexpr and string_view in module

现代 C++ 提供 constexprstd::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 namespaces) 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 方法的原始尝试不起作用的原因