简体   繁体   English

要求功能模板的返回类型是模板的专用化

[英]Require return type of function template to be specialization of a template

I've poked around on stackoverflow for a while, but either I don't understand templates enough to find a solution, or it simply hasn't been answered before. 我在stackoverflow上闲逛了一段时间,但要么我对模板的了解不足以找到解决方案,要么以前根本没有回答过。

In this example: 在此示例中:

template <typename T> T f();

Is it possible to make the function require type T to be a specialization of the std::basic_string template? 是否有可能使该函数要求类型T是std::basic_string模板的特殊化?

I could have the template defined with T as the type of the std::basic_string as so (using std::basic_string<T> internally, of course): 我可以将模板定义为T作为std::basic_string的类型(当然,内部使用std::basic_string<T> ):

template <typename T> std::basic_string<T> f();

But then I would not be able to pass std::string or std::wstring to the function (expecting the return type to be std::string and std::wstring , respectively), which is the real aim here (to be able to pass any type which derives from the std::basic_string template). 但是然后我将无法将std::stringstd::wstring传递给函数(期望返回类型分别为std::stringstd::wstring ),这才是真正的目标(成为能够传递从std::basic_string模板派生的任何类型)。

Partial specialization allows you to test whether a type is a specialization of a particular template. 部分专业化允许您测试类型是否是特定模板的专业化。 SFINAE is a trick that can "switch off" a function template declaration. SFINAE是一种可以“关闭”功能模板声明的技巧。 The solution combines these techniques. 该解决方案结合了这些技术。

template< typename T > // by default,
struct enable_if_basic_string {}; // a type is not a basic_string

template< typename CharT, typename Traits >
struct enable_if_basic_string< basic_string< CharT, Traits > > {
    typedef basic_string< CharT, Traits > type; // same as argument type
};

// enable_if_basic_string<>::type exists only if T specializes basic_string
// if not, compiler ignores function declaration per SFINAE.
template< typename T >
typename enable_if_basic_string< T >::type
F() {
    .....
}

If you mean derivation as well as specialization, you might take a look at std::tr1::is_convertible and enable_if as well. 如果您指的是推导和专业化,则可以看看std::tr1::is_convertibleenable_if

Instead of requiring that T be a specialization of std::basic_string , why not just assume that T is a specialization of std::basic_string and let template instantiation fail if it isn't. 除了不要求Tstd::basic_string ,为什么不仅仅假定 Tstd::basic_string化,并让模板实例化失败(如果不是)。 Just use the things from std::basic_string that you need. 只需使用您需要的std::basic_string中的内容即可。

For example, 例如,

template <typename T>
T get_first_three_chars(const T& str) { return str.substr(0, 3); }

Here, we assume that T has a member function substr ; 在这里,我们假设T具有成员函数substr if it doesn't, then instantiation will fail, resulting in a compilation error. 如果不是,则实例化将失败,从而导致编译错误。

This is not possible in vanilla C++. 在香草C ++中这是不可能的。 There was a language construct proposed for C++0x that would allow for this, unfortunately it was dropped. 提出了一种针对C ++ 0x的语言构造,可以允许这样做,但不幸的是它被删除了。

You can do this to a certain degree with the Boost Concept Check Library, however: http://www.boost.org/doc/libs/1_44_0/libs/concept_check/concept_check.htm 您可以使用Boost Concept Check Library在一定程度上做到这一点,但是: http : //www.boost.org/doc/libs/1_44_0/libs/concept_check/concept_check.htm

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM