Can a compilation error be forced if a string argument is not a string literal?

前端 未结 7 1914
说谎
说谎 2020-12-17 20:24

Let\'s say I have these two overloads:

void Log(const wchar_t* message)
{
    // Do something
}

void Log(const std::wstring& message)
{
    // Do someth         


        
7条回答
  •  抹茶落季
    2020-12-17 20:44

    So this grew out of Keith Thompson's answer... As far as I know, you can't restrict string literals to only normal functions, but you can do it to macro functions (through a trick).

    #include 
    #define LOG(arg) Log(L"" arg)
    
    void Log(const wchar_t *message) {
        std::wcout << "Log: " << message << "\n";
    }
    
    int main() {
        const wchar_t *s = L"Not this message";
        LOG(L"hello world");  // works
        LOG(s);               // terrible looking compiler error
    }
    

    Basically, a compiler will convert "abc" "def" to look exactly like "abcdef". And likewise, it will convert "" "abc" to "abc". You can use this to your benefit in this case.


    I also saw this comment on the C++ Lounge, and that gave me another idea of how to do this, which gives a cleaner error message:

    #define LOG(arg) do { static_assert(true, arg); Log(arg); } while (false)
    

    Here, we use the fact that static_assert requires a string literal as it's second argument. The error that we get if we pass a variable instead is quite nice as well:

    foo.cc:12:9: error: expected string literal
        LOG(s);
            ^
    foo.cc:3:43: note: expanded from macro 'LOG'
    #define LOG(arg) do { static_assert(true, arg); Log(arg); } while (false)
    

提交回复
热议问题