C++ 中嵌套结构的模板

问题描述 投票:0回答:2

我想编写这段代码,但它会产生错误。

template<int N>
struct A {
    struct B {

    };
    B f() { return B{}; }
};

template<typename T>
constexpr bool val = false;

template<int N>
constexpr bool val<typename A<N>::B> = true;
error: template parameters not deducible in partial specialization:
   13 | constexpr bool val<typename A<N>::B> = true;

虽然这段代码运行完美

template<int N> struct A;

template<int N>
struct AB {

};

template<int N>
struct A {
    AB<N> f() { return AB<N>{}; }
};

template<typename T>
constexpr bool val = false;

template<int N>
constexpr bool val<AB<N>> = true;

我理解C++在评估

N
时必须检查是否存在
T
使得
A<N>::B
等于
val<T>
,这太困难了。这就是为什么会出现错误。但我的问题是:有没有办法将结构体 B 保留在 A 中并为每个
val<A<N>::B>
定义值
N

我理解如果 B 被定义为对 A 外部结构的引用(例如

using B = int;
)的错误,但如果 B 是 A 内部定义的结构,则不会有歧义,并且
N
很容易推断出来。

c++ templates template-meta-programming
2个回答
2
投票

最简单的解决方案是在类外部定义它,并在类中使用类型别名来正常使用它:

template<int N> struct A;

template<int N>
struct AB {
    friend A<N>;
};

template<int N>
struct A {
    using B = AB<N>;
    friend B;
    B f() { return B{}; }
};

template<typename T>
constexpr bool val = false;

template<int N>
constexpr bool val<AB<N>> = true;

这和嵌套

struct B
之间几乎没有什么区别。


0
投票

您可以使用老式类型的特征,将测试分为两部分。

  1. 测试提供的类型是否为
    A<N>
  2. 测试
    A<N>
    是否定义类
    B
template<class T>
struct is_A_with_B {
    static std::false_type test(...);
    
    template<class U> // test that the A<N> has a class B
    static auto test2(U&&) -> class U::B;

    template<int N>   // if it's actually an A<N>, check test2 above
    static constexpr auto test(A<N>&&) -> decltype(test2(std::declval<A<N>>()),
                                                   std::true_type{});

    static constexpr bool value = decltype(test(std::declval<T>()))::value;
};

template<typename T>
constexpr bool val = is_A_with_B<T>::value;

演示

© www.soinside.com 2019 - 2024. All rights reserved.