你会如何在C#中进行专业化?
我会提出一个问题.你有一个模板类型,你不知道它是什么.但你知道它是否来自XYZ你想要打电话.alternativeFunc().一个很好的方法是调用一个专门的函数或类,并normalCall返回,.normalFunc()同时在任何派生类型的XYZ调用上具有其他特化.alternativeFunc().如何在C#中完成?
我知道语言规范禁止功能模板的部分特化.
我想知道为什么禁止它的理由?它们没用吗?
template<typename T, typename U> void f() {} //allowed!
template<> void f<int, char>() {} //allowed!
template<typename T> void f<char, T>() {} //not allowed!
template<typename T> void f<T, int>() {} //not allowed!
Run Code Online (Sandbox Code Playgroud) c++ language-design partial-specialization template-specialization function-templates
我知道下面的代码是类的部分特化:
template <typename T1, typename T2>
class MyClass {
…
};
// partial specialization: both template parameters have same type
template <typename T>
class MyClass<T,T> {
…
};
Run Code Online (Sandbox Code Playgroud)
另外我知道C++不允许函数模板部分特化(只允许完整).但是我的代码是否意味着我对一个/同一类型的参数有部分专业的函数模板?因为它适用于Microsoft Visual Studio 2010 Express!如果不是,那么请您解释部分专业化概念吗?
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
template <typename T1, typename T2>
inline T1 max (T1 const& a, T2 const& b)
{
return a < b ? b : a;
}
template <typename T>
inline T const& max (T const& a, T const& b)
{
return …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization template-specialization
假设我想编写一个泛型函数void f<T>(),如果T是POD类型则执行一项操作,如果T是非POD(或任何其他任意谓词)则执行另一项操作.
实现此目的的一种方法是使用标签库调用模式,如标准库与迭代器类别一样:
template <bool> struct podness {};
typedef podness<true> pod_tag;
typedef podness<false> non_pod_tag;
template <typename T> void f2(T, pod_tag) { /* POD */ }
template <typename T> void f2(T, non_pod_tag) { /* non-POD */ }
template <typename T>
void f(T x)
{
// Dispatch to f2 based on tag.
f2(x, podness<std::is_pod<T>::value>());
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是使用部分专用类型的静态成员函数:
template <typename T, bool> struct f2;
template <typename T>
struct f2<T, true> { static void f(T) { /* POD */ …Run Code Online (Sandbox Code Playgroud) c++ metaprogramming partial-specialization generic-programming
我有这个代码
template<int N, bool C = true>
struct A;
template<int N>
struct A<N, !(N % 5)> {
/* ... */
};
// should work
A<25> a;
Run Code Online (Sandbox Code Playgroud)
也就是说,对于N可被整除的数字,5编译器应使用部分特化.但编译器不会接受部分特化,因为标准要求它拒绝这样的代码,其中部分特化的非类型参数引用参数而不仅仅是一个参数(比如,A<N, N>是有效的).但是这样做的原因是什么?
请注意,我可以简单地将我的代码更改为更罗嗦的示例,它是有效的
template<bool> struct wrap;
template<int N, typename = wrap<true> >
struct A;
template<int N>
struct A<N, wrap<!(N % 5)> > {
/* ... */
};
// should work
A<25> a;
Run Code Online (Sandbox Code Playgroud)
这很好,因为它不再是非类型参数.但是,规范禁止更直接的部分专业化的原因是什么?
以下是来自libstdc ++的一些部分特化:std::is_function<type_traits>
/// is_function
template<typename>
struct is_function
: public false_type { };
template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes...)>
: public true_type { };
template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes...) &>
: public true_type { };
template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes...) &&>
: public true_type { };
template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes......)>
: public true_type { };
template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes......) &>
: public true_type { };
template<typename _Res, typename... _ArgTypes>
struct is_function<_Res(_ArgTypes......) …Run Code Online (Sandbox Code Playgroud) c++ templates partial-specialization variadic-templates c++11
以下代码:
template <typename S, typename T>
struct foo {
void bar();
};
template <typename T>
void foo <int, T>::bar() {
}
Run Code Online (Sandbox Code Playgroud)
给了我错误
invalid use of incomplete type 'struct foo<int, T>'
declaration of 'struct foo<int, T>'
Run Code Online (Sandbox Code Playgroud)
(我正在使用gcc.)我的部分特化的语法错了吗?请注意,如果我删除第二个参数:
template <typename S>
struct foo {
void bar();
};
template <>
void foo <int>::bar() {
}
Run Code Online (Sandbox Code Playgroud)
然后它正确编译.
也许我累了,但我坚持这个简单的部分专业化,这不起作用,因为non-type template argument specializes a template parameter with dependent type 'T':
template <typename T, T N> struct X;
template <typename T> struct X <T, 0>;
Run Code Online (Sandbox Code Playgroud)
更换0的T(0),T{0}或(T)0没有帮助.那么这种专业化甚至可能吗?
多个类模板特化是否有效,当每个模板特化仅在涉及非推导上下文中的模板参数的模式之间不同时?
一个常见的例子是std::void_t使用它来定义一个特征,它揭示了一个类型是否有一个typedef名为"type" 的成员.这里采用单一专业化.这可以扩展到鉴定说类型是否有任何成员typedef被称为"TYPE1",或者一个名为"2型".下面的C++ 1z代码用GCC编译,但不是Clang.这合法吗?
template <class, class = std::void_t<>>
struct has_members : std::false_type {};
template <class T>
struct has_members<T, std::void_t<typename T::type1>> : std::true_type {};
template <class T>
struct has_members<T, std::void_t<typename T::type2>> : std::true_type {};
Run Code Online (Sandbox Code Playgroud) c++ partial-specialization sfinae template-specialization c++17
有谁知道,在C++ 11中,函数模板是否可以部分专用?