const char *,const char(&)[N]和std :: string的函数重载

时间:2016-01-05 21:38:49

标签: c++ string overloading

我想要实现的是具有适用于字符串文字和std::string的函数的重载,但会为const char*参数产生编译时错误。以下代码几乎完全符合我的要求:

#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)产生编译时错误而不影响其他重载?

3 个答案:

答案 0 :(得分:3)

为了使的已删除函数与模板函数更好地匹配,以便字符串文字仍然有效,删除的函数也需要是模板。这似乎满足您的要求(尽管仍允许数组):

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

Demo.

答案 1 :(得分: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);
}

答案 2 :(得分:1)

在该语言的现代版本中,您可以创建一些自定义类型和用户定义的文字来创建它,以便可以传递"this"_SOMEWORDS,但不仅仅是c字符串文字,聊天指针或字符阵列。

它并不能完全满足您传递字符串文字的要求,但我认为它足够好,特别是因为它也禁止数组