2016-03-20 8 views
2

私は、次の3つのC++のファイルを持っている(すべては1つのファイル内にある場合、問題は発生しません):constexpr関数ではconstポインタへの参照を返すが、コピーを返さないのはなぜですか?

clazz.hpp:

class Clazz { 
    public: 
     static const char* const NAME; 
}; 

clazz.cpp:

#include "clazz.hpp" 
const char* const Clazz::NAME = "Clazz"; 

メインを.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でコンパイルすると、エラーm get_clazz_name機能のためにessage:Funnily十分

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

は、機能 get_clazz_name_refはOKコンパイルされます。どうしてこんなことに?


アラン・ストークスに応答して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

すべてを同じファイルに入れるとコードがコンパイルされません。 – Holt

+0

うーん、私はそれが私のためにコンパイルしたと思った。たぶん私はエラーメッセージを見逃しました。 –

+0

どのコンパイラを使用していますか?たぶん、あなたはコンパイルする完全なコードを投稿することができますか?これは、Visual Studio 2015年に私のためにコンパイル – Holt

答えて

4

NAMEのアドレスは、main.cppをコンパイルするときにコンパイラに知られていますが、その値はありません。そのため、この値はコンパイル時定数にはなりません。その後、初期化子があるので、彼らは一つのファイルにしている場合には適用されません

;

(それは定数にすることはできませんので、あなたが唯一のclazz.cppを変更して再構築し、それに異なる値を与えることができます。)その値は既知である。

+0

私はあなたの説明を得ていますが、 'clazz.cpp'で定義されている' Clazz'の 'std :: array'メンバーから' const char * 'の値を抜き出す方法は' constexpr'とすることができます。 –