[英]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::string
或std::wstring
传递给函数(期望返回类型分别为std::string
和std::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_convertible
和enable_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. 除了不要求
T
为std::basic_string
,为什么不仅仅假定 T
为std::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.