C++ 类模板,它独立于其参数的排列

C++ 类模板,它独立于其参数的排列,c++,c++11,class-template,C++,C++11,Class Template,考虑定义如下的类模板和辅助枚举类: enum class Color {Red, Green, Blue} enum class ShowAxes {False, True} enum class ShowLabels {False, True} template< Color, ShowAxes, ShowLabels > class A {......}; enum类颜色{红、绿、蓝} 枚举类ShowAxes{False,True} 枚举类ShowLabels{False,T

考虑定义如下的类模板和辅助枚举类:

enum class Color {Red, Green, Blue}
enum class ShowAxes {False, True}
enum class ShowLabels {False, True}

template< Color, ShowAxes, ShowLabels >
class A
{......};
enum类颜色{红、绿、蓝}
枚举类ShowAxes{False,True}
枚举类ShowLabels{False,True}
模板<颜色、显示轴、显示标签>
甲级
{......};
问题是,如何重新定义类A,它将独立于其参数的排列。我使用DEVC++,支持C++ 11。 [编辑]

例如,新版本的A应该支持

A< Color::Red, ShowAxes::True, ShowLabels::True >
A< Color::Red, ShowLabels::True, ShowAxes::True >
A< ShowAxes::True, Color::Red, ShowLabels::True >
A< ShowLabels::True, Color::Red, ShowAxes::True >
A< ShowLabels::True, Color::Red, ShowAxes::True >
A< ShowAxes::True, Color::Red, ShowLabels::True >
A
A
A
A
A
A
版本,并且它们都是相同的,即它们生成相同的类。

可能通过使用。然后,您可以通过以下方式简化代码:

template <typename A, typename B, typename C>
class X
{
public:
    X() {
        static_assert(
            std::is_same<A, Color>::value ||
            std::is_same<B, Color>::value ||
            std::is_same<C, Color>::value,
            "nope");
        // other assertions here!
        // also, make sure your types are different ;)
    }
    X(A a, B b, C c) : X() {
        // your code here
    }
};

template <typename A, typename B, typename C>
X<A, B, C> make(A a, B b, C c) {
    // possible verifications here
    return X<A, B, C>(a, b, c);
}

int main() {
    auto a = make(Color::Red, ShowAxes::true, ShowLabels::True);
    return 0;
}
模板
X类
{
公众:
X(){
静态断言(
std::值是否相同||
std::值是否相同||
std::值是否相同,
“否”);
//这里还有其他断言!
//另外,请确保您的类型不同;)
}
X(aa,bb,cc):X(){
//你的代码在这里
}
};
模板
X品牌(A、B、C){
//此处可能的验证
返回X(a、b、c);
}
int main(){
自动a=make(颜色::红色,显示轴::true,显示标签::true);
返回0;
}
您可以验证所有类型A、B和C


很抱歉,我看不到其他解决办法/

当前接口使用非类型参数是不可能的

您可以改为使用类型参数,并将值包装在
std::integral\u常量中

template<class X, class Y, class Z>
class A { /* stuff */ };

// use as:
A<std::integral_constant<Color, Color::Red>,
  std::integral_constant<ShowAxes, ShowAxes::True>,
  std::integral_constant<ShowLabels, ShowLabels::True>> a;
那你就可以了

// inside the definition of A
static constexpr Color col = extract<Color, X, Y, Z>::value;
现在给出

A<AS_IC(Color::Red), AS_IC(ShowAxes::True), AS_IC(ShowLabels::True)> a;
A<AS_IC(Color::Red), AS_IC(ShowLabels::True), AS_IC(ShowAxes::True)> b;

C++类模板特化?@ BryanChen。不能用专门化来改变参数类型。我不想改变参数的类型。专业化是个好主意,但我有3个!=6个排列。此外,我将添加更多的参数。对于不同类型的非类型参数,这是不可能的。您可以使用类型参数,并将值封装在类型中,如
std::integral_constant
,但它很快就会变得冗长。我在问题中添加了一些文本,以详细解释我的目标。谢谢,但例如
make(颜色::红色,ShowAxes::True,ShowLabels::True)
make(显示轴::真,颜色::红色,显示标签::真)
给出不同的结果。它们应该生成相同的类。继承能解决问题吗?如果X类继承自基类,由于多态性,它们可以是相同的类型。
std::integral_constant
extract
的想法看起来不错。我会考虑优化代码。我有一个小建议(可能是一个无关紧要的)问题。有没有可能用非指令人员(比如类模板或模板函数)来替换宏?@VahagnPoghosyan在声明
a
时,如果不添加大量样板文件,我知道没有宏自由的方式。
template<class Result, class...>
struct extract;

template<class Result, Result Value, class... Tail>
struct extract<Result, std::integral_constant<Result, Value>, Tail...> : std::integral_constant<Result, Value> {};

template<class Result, class Head, class... Tail>
struct extract<Result, Head, Tail...> : extract<Result, Tail...> {};
// inside the definition of A
static constexpr Color col = extract<Color, X, Y, Z>::value;
template< Color, ShowAxes, ShowLabels >
class A_impl
{/* stuff */};

template<class X, class Y, class Z>
using A = A_impl<extract<Color, X, Y, Z>::value,
                 extract<ShowAxes, X, Y, Z>::value,
                 extract<ShowLabels, X, Y, Z>::value>;
A<AS_IC(Color::Red), AS_IC(ShowAxes::True), AS_IC(ShowLabels::True)> a;
A<AS_IC(Color::Red), AS_IC(ShowLabels::True), AS_IC(ShowAxes::True)> b;
template< Color c, ShowAxes a, ShowLabels l>
A<c,a,l> A_of();

template< ShowAxes a, ShowLabels l, Color c>
A<c,a,l> A_of();

// etc.

decltype(A_of<Color::Red, ShowAxes::True, ShowLabels::True>()) a1;
decltype(A_of<ShowAxes::True, ShowLabels::True, Color::Red>()) a2;