为什么在constexpr函数中返回对const指针的引用,但不返回副本?

时间:2016-03-20 09:24:06

标签: c++ constexpr

我有以下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并重建。

1 个答案:

答案 0 :(得分:4)

编译NAME时编译器知道main.cpp的地址,但其值不是。所以该值不能是编译时常量。

(你可以只改变clazz.cpp并重建,给它一个不同的值;所以它不能是常数。)

当它们位于一个文件中时不适用,因为初始化程序可见且值已知。