我有以下3个C ++文件(如果所有文件都在1个文件中,则不会出现此问题):
clazz.hpp:
class Clazz {
public:
static const char* const NAME;
};
clazz.cpp:
#include "clazz.hpp"
const char* const Clazz::NAME = "Clazz";
main.cpp中:
#include <iostream>
#include "clazz.hpp"
constexpr const char* const& get_clazz_name_ref() {
return Clazz::NAME;
}
constexpr const char* get_clazz_name() {
return Clazz::NAME; // this does not work
}
int main(void) {
std::cout << get_clazz_name_ref() << std::endl;
std::cout << get_clazz_name() << std::endl;
}
在Visual Studio 2015中编译此文件时,我收到get_clazz_name
函数的错误消息:
error C3256: 'NAME': variable use does not produce a constant expression
有趣的是,函数get_clazz_name_ref
编译好了。为什么会这样?
回应艾伦·斯托克斯https://stackoverflow.com/a/36112146/59557:为什么这有效?
clazz.hpp:
#include <array>
class Clazz {
public:
static const char* const NAME;
static const size_t N = 3;
static const std::array<const char*, N> NAMES;
};
clazz.cpp:
#include "clazz.hpp"
const char* const Clazz::NAME = "Clazz";
const std::array<const char*, Clazz::N> Clazz::NAMES = {
"A",
"B",
"C"
};
main.cpp中:
#include <iostream>
#include "clazz.hpp"
constexpr const char* const& get_clazz_name_ref() {
return Clazz::NAME;
}
constexpr const char* get_name(size_t i) {
return Clazz::NAMES[i];
}
int main(void) {
std::cout << get_clazz_name_ref() << std::endl;
std::cout << get_name(0) << std::endl;
}
我也可以更改clazz.cpp
并重建。
答案 0 :(得分:4)
编译NAME
时编译器知道main.cpp
的地址,但其值不是。所以该值不能是编译时常量。
(你可以只改变clazz.cpp
并重建,给它一个不同的值;所以它不能是常数。)
当它们位于一个文件中时不适用,因为初始化程序可见且值已知。