我有以下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
编译正确。为什么呢?回应Alan Stokes 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
并重新构建。 最佳答案
编译NAME
时,编译器会知道main.cpp
的地址,但其值不是。因此,该值不能是编译时常量。
(您可以仅更改clazz.cpp
并进行重建,以为其提供不同的值;因此它不能恒定。)
当它们在一个文件中时,这将不适用,因为这样便可以看到初始化程序并且知道值。
关于c++ - 为什么在constexpr函数中允许返回对const指针的引用,但不返回拷贝?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36112052/