gpt4 book ai didi

c++ - 嵌套模板类的模板类模板参数特化

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:34 25 4
gpt4 key购买 nike

通常您可以针对实例化的模板类部分特化模板类。例如

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 Orspecialize_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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com