简体   繁体   中英

Why is returning a reference to const pointer allowed in constexpr function, but not returning a copy?

I have the following 3 C++ files (the problem does not occur if all are in 1 file):

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;
}

When compiling this files in Visual Studio 2015, I get an error message for the get_clazz_name function:

error C3256: 'NAME': variable use does not produce a constant expression

Funnily enough, the function get_clazz_name_ref is compiled OK. Why is that so?


In response to Alan Stokes https://stackoverflow.com/a/36112146/59557 : why is this working?

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;
}

I could change clazz.cpp and rebuild, too.

The address of NAME is known to the compiler when compiling main.cpp but its value isn't. So the value can't be a compile-time constant.

(You could change clazz.cpp only and rebuild, to give it a different value; so it can't be constant.)

That doesn't apply when they're in one file because then the initialiser is visible and the value is known.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM