假设我有自定义字符串类:
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")
)?
答案 0 :(得分:3)
对“从字符串参数构造”进行细化。
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});
}
答案 1 :(得分:1)
你真的需要一个功能模板吗?简单的功能:
my_string do_something(my_string const& input) { ... }
解决您的用例。您可以传入my_string
或字符串文字,甚至是 braced-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
提供默认值。这个默认值无法有意义地使用。
答案 2 :(得分:1)
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
的重载转发到函数模板。