0
對於a similar SO question我想出了以下解決方案:限制傳遞的參數的非暫時性的字符串字面
#include <cstdlib>
class Literal
{
public:
template <std::size_t N> constexpr
Literal(const char (&str)[N])
: mStr(str),
mLength(checkForTrailingZeroAndGetLength(str[N - 1], N))
{
}
template <std::size_t N> Literal(char (&str)[N]) = delete;
constexpr operator const char*() const noexcept
{
return mStr;
}
constexpr const char* c_str() const noexcept
{
return mStr;
}
private:
const char* mStr;
std::size_t mLength;
struct Not_a_CString_Exception{};
constexpr static
std::size_t checkForTrailingZeroAndGetLength(char ch, std::size_t sz)
{
return (ch) ? throw Not_a_CString_Exception() : (sz - 1);
}
};
它非常好,但它仍然有可能要創建從自動存儲時間陣列一個文字。我希望在編譯時避免這種情況。下面的例子是未定義行爲:
#include <cstdio>
static Literal okay()
{
static constexpr const char okay[] = "okay";
return { okay };
}
static Literal boom()
{
const char boom[] = "boom"; //Oops, static forgotten
return { boom }; // <= How to force a compile error here?
}
int main()
{
printf("%s\n", okay().c_str()); // <= the intended use case
printf("%s\n", boom().c_str()); // <= the undefined behaviour
return 0;
}
它也可以在godbolt compiler explorer找到。是否有可能在編譯時檢測到這個用例並強制編譯錯誤?
你爲什麼不堅持使用該文本操作方式 – Sopel
其實我們使用的文字有一段時間了,從來沒有絆倒在這個陷阱,因爲我們的開發人員通常採取的字面操作方式。另一方面,如果一個開發人員出於任何原因編寫這樣的構造,我寧願在編譯時捕獲它,而不是無盡的調試會話。 –
聽起來你應該只是使應用構造函數的私人和文本操作模板的朋友。 –