通过传递const char*隐式地选择字符串模板

Select string template implicitly by passing const char*

本文关键字:选择 字符串 const char      更新时间:2023-10-16

假设我有一个自定义字符串类:

class my_string : public std::string
{
    // ...
}

我想创建一个模板函数,默认情况下接受my_string:

template <typename TString = my_string>
TString do_something(const TString& input)
{
    // ...
}

但是当我用:

auto result = do_something("abcdef");

它调用(当然)do_something<char[7]>()。如何强制它调用do_something<my_string> 而不显式地指定类型(即写do_something("abcdef"),而不是do_something<my_string>("abcdef")) ?

指定"从字符串参数构造"

template <typename TString = my_string,
typename std::enable_if<std::is_base_of<std::string, TString>::value>::type = nullptr>
TString do_something(const TString& input)
{
    // ...
}
template <typename ...Args,
typename std::enable_if<std::is_constructible<my_string, Args....>::value>::type = nullptr>
my_string do_something(Args&&... args)
{
    return do_something<my_string>({args});
}

你真的需要函数模板吗?简单的函数:

my_string do_something(my_string const& input) { ... }

解决您的用例。您可以传入my_string或字符串字面值,甚至是带括号的init-list,一切都可以正常工作。


由于其他原因需要模板,您可以简单地为const char数组提供重载:

template <class TString>
TString do_something(TString const&) { ... }
template <size_t N>
my_string do_something(const char (&arr)[N]) {
    return do_something(my_string{arr, N-1});
}

注意:没有理由为模板参数TString提供默认值。没有办法有意义地使用这个默认值。

Re

我想创建一个模板化函数,默认接受my_string

#include <string>
template< class Type >
struct Explicit_t_ { using T = Type; };
template< class Type >
using Explicit_ = typename Explicit_t_<Type>::T;
namespace my {
    struct String: std::string { using std::string::string; };
}  // namespace my
template< class Some_string >
auto do_something( Explicit_<Some_string> const& )
    -> Some_string
{ return "Template func!"; }
auto do_something( my::String const& )
    -> my::String
{ return "my::String!"; }
#include <iostream>
using namespace std;
auto main()
    -> int
{
    cout << do_something( "" ) << endl;       // Output "my::String!"
    cout << do_something<std::string>( "" ) << endl;
}

您可以让my::String的重载直接转发给函数模板,除非您想要更专门或不同的实现。