重载char指针和字符串文字

时间:2014-12-21 15:36:57

标签: c++

我正在尝试创建一个可以接受(并且可以消除歧义)字符串文字的类。在搜索此问题时,提供的解决方案是创建一个只能接受char指针的“holder”类:

template< typename char_t >
class String
{
    struct holder_t
    {
        const char_t* s;
        holder_t( const char_t* s ) : s(s) {}
        holder_t( char_t* s ) : s(s) {}
    };
public:

    // Construct from string literal
    template< size_t S >
    String( const char_t (&str)[S] )
    {
        std::cout << "String Literal: " << str;
    }

    // Construct from char pointer
    String( holder_t h )
    {
        std::cout << "Char Pointer: " << h.s;
    }
};

最大的想法是你永远不必显式创建这个类的实例,它应该通过隐式转换来实现:

void StringFoo( String<char> s )
{
}

但是这会导致char指针的编译错误,为什么隐式转换不起作用?

int main()
{
    // Works!
    StringFoo( "literal" );

    // error C2664: 'StringFoo' : cannot convert parameter 1 from 'const char *' to 'String<char_t>'
    // with [ char_t=char ]
    // No constructor could take the source type, or constructor overload resolution was ambiguous
    StringFoo( (const char*)"const char ptr" );

    // Works!
    StringFoo( String<char>((const char*)"const char ptr") );

    // error C2664: 'StringFoo' : cannot convert parameter 1 from 'char *' to 'String<char_t>'
    // with [ char_t=char ]
    // No constructor could take the source type, or constructor overload resolution was ambiguous
    StringFoo( (char*)"char ptr" );

    // Works!
    StringFoo( String<char>((char*)"const char ptr") );

    return 0;
}

这只是一个简单的无意义的例子;在我的真实代码中,我创建了一个将保存字符串哈希值的类。

如果传递字符串文字并在运行时计算(如果传递了char指针),则应在编译时生成散列。

然而,这应该对刚刚传递字符串的用户完全透明,哈希是自动完成的。

2 个答案:

答案 0 :(得分:1)

要从字符串文字到String,需要进行两次用户定义的转换 - 一次转换为holder_t,另一次转换为String。但是重载决策只允许你为每个参数进行一次这样的转换。

答案 1 :(得分:1)

代码无法使用指针的原因是它需要两个版本(char const*holderholderString。但是,隐式转换会做最多一次转换。

出于您描述的目的,我认为您可以合理地区分char const(&)[N]char const*:因为您总是想要计算哈希值而只是让它成为{{1}在可能的情况下,使constexpr引用的版本应该成功。