- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
通常您可以针对实例化的模板类部分特化模板类。例如
template<class T>
struct specialize_me {};
template<class T>
struct specialize_me<std::vector<T>> {
static const int foo = 3;
};
模板类specialize_me
部分专门针对实例化的模板类 std::vector<T>
. specialize_me
时选择此专业用 std::vector<T>
实例化, 对于任何类 T
.
int main() {
std::cout << specialize_me<std::vector<int>>::foo; // Compiles.
}
但是,我不知道如何针对实例化的嵌套模板类专门化模板模板类:
// Nested template class.
template<class T>
struct Either {
template<class U>
struct Or {};
};
template<template<class> class T>
struct specialize_me_2 {};
template<class T>
struct specialize_me_2<Either<T>::template Or> {
static const int foo = 3;
};
在这种情况下,当我实例化 specialize_me_2
时,未选择特化同类Either<T>::template Or
对于任何类(class) T
.我的猜测是,发生这种情况是因为编译器必须确认或拒绝“存在一个 T
,使得 Either<T>::template Or
与 specialize_me_2
实例化的类型相同”,以便选择我的特化,但它不是编程也未指定这样做。
int main() {
std::cout << specialize_me_2<Either<int>::Or>::foo; // Does not compile. 'foo' is not a member of specialize_me_2<Either<int>::Or>.
}
有没有办法专门化specialize_me_2
这样每当 specialize_me_2
时都会选择特化用 Either<T>::Or
实例化对于任何 T
?
这Either
struct 最终将表示一个错误携带类型,所以 Either<T>
表示T
是错误类型,Either<T>::Or<U>
表示U
是成功计算携带的类型。
如果这是不可能的,我可能仍然可以使用 #define
s 使您能够定义 Either<T>
对于每个 T
根据需要,#define
还包括 specialize_me_2
特定的特化 Either<T>::Or
.事实上,我打算使用 Either
通过编写在程序中构造 template<class T> using FooError = Either<Foo>::Or<T>
无论如何然后写FooError<Bar>
, FooError<Quux>
等等,所以使用它不会对预期用途有很大的影响。
最佳答案
有趣的问题。
要轻松解决它...如果您可以添加新的 using
在里面输入 Or
template <typename T>
struct Either
{
template <typename>
struct Or
{ using specialOrType = T; };
};
然后你可以添加第二个模板参数,一个带有void
的类型名默认情况下,在 specialize_me_2
template <template <typename> class C, typename = void>
struct specialize_me_2
{ static const int foo = 2; };
并在 specialOrType
上使用 SFINAE
template <typename ...>
using myVoidT = void;
template <template <typename> class C>
struct specialize_me_2<C, myVoidT<typename C<void>::specialOrType>>
{
using T = typename C<void>::specialOrType;
static const int foo = 3;
};
您获得工作特化。
而不是 myVoidT
, 从 C++17 开始,你显然可以使用 std::void_t
.
观察到这样你不能推导出原来的T
输入,但您可以通过 specialOrType
恢复它.
还请注意,这需要(aschepler 指出的)Or<void>
是一个有效的特化。如果不是这种情况,您应该选择其他类型 X
这样Or<X>
是对所有 Either<T>
的有效特化.例如,假设 Or<int>
是每个 Either<T>
的有效特化, 特化成为
template <template <typename> class C>
struct specialize_me_2<C, myVoidT<typename C<int>::specialOrType>>
{
using T = typename C<int>::specialOrType;
static const int foo = 3;
};
下面是一个完整的工作示例
#include <iostream>
template <typename ...>
using myVoidT = void;
template <typename>
struct NoEither
{ };
template <typename T>
struct Either
{
template <typename>
struct Or
{ using specialOrType = T; };
};
template <template <typename> class C, typename = void>
struct specialize_me_2
{ static const int foo = 2; };
template <template <typename> class C>
struct specialize_me_2<C, myVoidT<typename C<void>::specialOrType>>
{
using T = typename C<void>::specialOrType;
static const int foo = 3;
};
int main ()
{
std::cout << specialize_me_2<NoEither>::foo << std::endl;
std::cout << specialize_me_2<Either<int>::template Or>::foo << std::endl;
}
关于c++ - 嵌套模板类的模板类模板参数特化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50894987/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!