我有以下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/

10-10 21:23