2016-01-05 166 views
3

我想要實現的是重載函數的重載,它適用於字符串文字和std::string,但會產生編譯時錯誤const char*參數。下面的代碼做幾乎什麼,我想:函數重載爲const char *,const char(&)[N]和std :: string

#include <iostream> 
#include <string> 

void foo(const char *& str) = delete; 

void foo(const std::string& str) { 
    std::cout << "In overload for const std::string&  : " << str << std::endl; 
} 

template<size_t N> 
void foo(const char (& str)[N]) { 
    std::cout << "In overload for array with " << N << " elements : " << str << std::endl; 
} 

int main() { 
    const char* ptr = "ptr to const"; 
    const char* const c_ptr = "const ptr to const"; 
    const char arr[] = "const array"; 
    std::string cppStr = "cpp string"; 

    foo("String literal"); 
    //foo(ptr); //<- compile time error 
    foo(c_ptr); //<- this should produce an error 
    foo(arr); //<- this ideally should also produce an error 
    foo(cppStr); 
} 

我不開心,它編譯爲char數組變量,但我覺得這是沒有辦法解決它,如果我想接受字符串(如果有請告訴我)

但是我想避免的是,std::string超載接受const char * const變量。不幸的是,我不能只聲明一個需要const char * const&參數的已刪除過載,因爲它也會匹配字符串文字。

任何想法,我怎麼可以讓foo(c_ptr)產生一個編譯時錯誤,而不會影響其他重載?

+0

char *數組和字符串的類型之間沒有區別*,所以你不能在沒有其他數據的情況下拋出一個。但我認爲你的其他要求是可以滿足的。 –

+0

@Tavian Barns:我想知道如果可以使用這個事實,字符串文字也是一個常量表達式(當然你也可以創建一個constexpr數組) – MikeMB

回答

3

此代碼需要什麼(數組除外 - 文字是數組,所以你不能將它們分開)

#include <cstddef> 
#include <string> 

template <class T> 
void foo(const T* const & str) = delete; 

void foo(const std::string& str); 

template<std::size_t N> 
void foo(const char (& str)[N]); 

int main() { 
    const char* ptr = "ptr to const"; 
    const char* const c_ptr = "const ptr to const"; 
    const char arr[] = "const array"; 
    std::string cppStr = "cpp string"; 

    foo("String literal"); 
    //foo(ptr); //<- compile time error 
    // foo(c_ptr); //<- this should produce an error 
    foo(arr); //<- this ideally should also produce an error 
    foo(cppStr); 
} 
+0

謝謝。使用該模板函數,我相信第一個重載(對於const char *&str')不再需要 - 對吧? – MikeMB

+0

是的,當然:) – SergeyA

1

在現代語言版本中,您可以創建一些自定義類型和用戶定義的文字來創建它,以便可以傳遞"this"_SOMEWORDS,但不僅僅是c字符串文字,聊天指針或字符數組。

它並不完全滿足您的要求,通過字符串文字,但我認爲這是不夠好,特別是因爲它禁止也陣列

+0

這實際上是一個非常有趣的想法,因爲它允許區分在char數組和字符串之間。但它不會阻止'std :: string'重載接受'const char * const'參數。 – MikeMB

+0

@MikeMB只要刪除它(const char * overload)現在可以工作 – RiaD

+0

對 - 對不起,它遲到了。是否有可能在編譯時獲得字符串文字的長度(就像我在模板參數中的函數中那樣)? – MikeMB

3

爲了使您的刪除功能比模板更好的匹配函數,以便字符串文字仍然有效,刪除的函數也需要成爲模板。這似乎滿足您的需求(儘管陣列仍然是允許的):

template <typename T> 
typename std::enable_if<std::is_same<std::decay_t<T>, const char*>::value>::type 
foo(T&& str) = delete; 

Demo.

+0

......這就是我要做的,但你打敗了我:) –

+0

SFINAE在這裏不是必需的。 – SergeyA

+0

謝謝,我總是忘記那 – MikeMB

相關問題