2016-01-05 164 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

相关问题