c++ 相同全模板特化

pexxcrt2  于 2023-01-15  发布在  其他
关注(0)|答案(3)|浏览(135)

将模板类完全专门化为已定义的专门化的正确语法是什么?
例如,在下面的代码中,如何将A<2>声明为A<0>的别名?

template <int I>
struct A;

template <>
struct A<0> { int x; };

template <>
struct A<1> { int y; };

template <>
using A<2> = A<0>; // error: expected unqualified-id before 'using'

注意:对于上面的代码,专门化A<1>并定义非专门化的A(如A<0>)就足够了:

template <int I>
struct A { int x; };

template <>
struct A<1> { int y; };

但是如果你遇到更复杂的情况,这就不起作用了,对于一组值你有一个专门化,对于另一组值你有另一个专门化,等等...

ctrmrzij

ctrmrzij1#

我不确定我是否理解了你的问题,因为你通过尝试解决它来描述它。
下面是我实现类似结果的方法:

struct Ax { int x; };

struct Ay { int y; };

template <int I>
struct Aselector;

template<>
struct Aselector<0>{
    using type = Ax;
};

template<>
struct Aselector<1>{
    using type = Ay;
};

template<>
struct Aselector<2>{
    using type = Ax;
};

template <int I>
using A = typename Aselector<I>::type;

https://godbolt.org/z/fGxcoE5xd
使用类型特征的版本更短:

#include <type_traits>

struct Ax { int x; };

struct Ay { int y; };

template <int I>
using A = std::conditional_t<I == 1, Ay, std::enable_if_t<I >= 0 && I <= 2, Ax>>;

https://godbolt.org/z/vMqPahfEo

js81xvg6

js81xvg62#

更复杂的情况,对于一组值有一个专门化,对于另一组值有另一个专门化,等等...
在这里,一定程度的间接性会有所帮助。

#include <iostream>
#include <type_traits>

template <size_t I> struct selector { static const size_t value = I; };    
template <> struct selector<2> { static const size_t value = 0;};
    
template <size_t J> struct Foo_impl { int x; };
template <> struct Foo_impl<1> { int y; };

template <size_t I> using Foo = Foo_impl< selector<I>::value >;
    
int main() {
    std::cout << std::is_same_v< Foo<0> , Foo<2> > << "\n";
    
    Foo<0> f0;
    f0.x = 42;
    Foo<1> f1;
    f1.y = 0;
    Foo<2> f2;
    f2.x = 123;
}

Foo<0>Foo<2>是同一类型。您可以向Foo_impl添加更多专门化,并且可以在模板参数I和专门化J的实际索引之间添加更多Map。

e3bfsja2

e3bfsja23#

其他答案应该可以,我只是想提供一个基于SFINAE的解决方案:

#include <iostream>

template <int I, typename = void>
struct A;

template <int I>
struct A<I, std::enable_if_t<I == 0 || I == 2>> { int x; };

template <typename Conditional>
struct A<1, Conditional> { int y; };

int main()
{
    std::cout << A<0>{}.x << std::endl;
    std::cout << A<1>{}.y << std::endl;
    std::cout << A<2>{}.x << std::endl;

    return 0;
}

注意:虽然这段代码允许A<0>A<2>共享一个实现,但是它们不会是相同的类型。std::is_same_v<A<0>, A<2>>对于其他答案将返回true,但对于这个答案将返回false。

相关问题