2016-09-28 19 views
6

は、私は私のカスタム文字列クラスがあるとします。選択した文字列のテンプレート*

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

そして、私は、デフォルトでは、両方のmy_stringで受け入れテンプレート機能作りたい:

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

をしかし、私がそれを呼び出すときに:。 do_something<my_string>明示的に指定することなく(つまりdo_something("abcdef")ではなくdo_something<my_string>("abcdef"))指定しないで強制的に呼び出す方法

+1

注:単なる例ですが、std :: string! –

+6

私は 'const char []'のオーバーロードを追加して、呼び出す関数に転送します。 – NathanOliver

+1

リテラル文字列接尾辞は、代わりに '' abcdef 's''と '' operator "" _my_s'' "" abcdef "_my_s'を助けるかもしれません。 – Jarod42

答えて

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

本当に機能テンプレートが必要ですか?シンプルな関数:

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。そのデフォルトを意味のある方法で使用する方法はありません。

+1

'my_string'を返します。これは' std :: string'を使う古いコードでは望ましくありません。 – vladon

+0

実際に配列を参考にしたいですか?配列やポインタを渡すことができるので、 'const char []'パラメータがもっと便利だと思います。 – NathanOliver

+0

@ NathanOliver文字列リテラルをキャプチャする方が好きです。 – Barry

1

私はあなたが関数テンプレートにちょうど前方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との両方を受け入れテンプレート機能を作りたいですより特殊化された実装や異なる実装が必要な場合を除きます。

関連する問題