gpt4 book ai didi

c++ - 使用 enable_if 仅匹配具有特定静态数据成员且仅具有特定值的类

转载 作者:搜寻专家 更新时间:2023-10-31 02:05:02 24 4
gpt4 key购买 nike

我想为类的一个子集特化一个函数,它:有一个特定的静态数据成员变量,并且这样的变量只有特定的可能值。

下面的代码说明了意图,但它不会编译,除非我在 main 中注释掉与 B 类相关的行。这是因为 code 不是 Bx 类的成员,但如果模板参数具有 code,则 enable_if 条件有效 成员变量。应该如何修改?

不幸的是,我使用的是非常旧的编译器,因此不支持 C++11:我使用选项 -std=c++03 进行编译。

谢谢

#include <iostream>
#include <boost/core/enable_if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/mpl/not.hpp>
#include <boost/mpl/bool.hpp>
using std::cout;
using namespace boost;
using namespace boost::mpl;

template <int N> struct A1 { static const int code = N; };
template <int N> struct A2 { static const int code = N; };
// ... other classes with static data member 'code'
template <int N> struct AN { static const int code = N; };

struct B1{};
struct B2{};
// ... other classes potentially passd as argument to the foo function
struct BN{};

template <typename T>
struct Condition : or_<bool_<T::code == 1>, bool_<T::code == 2> > {};


template <typename T>
typename enable_if<not_<Condition<T> >, void>::type
foo(const T& arg) { cout << "This class does not have a static member code or its value is not 1 or 2\n"; }

template <typename T>
typename enable_if<Condition<T>, void>::type
foo(const T& arg) { cout << "This class has a static member code and its value is " << T::code << "\n"; }

int main()
{
foo(A1<0>()); // this should match the 1st version of foo
foo(A2<1>()); // this should match the 2nd version of foo
foo(AN<2>()); // this should match the 2nd version of foo
foo(B1()); // this should match the 1st version of foo
foo(BN()); // this should match the 1st version of foo
}

最佳答案

真正的问题是您需要一个 C++03 解决方案,因此您可以使用 SFINAE 但不是所有从 C++11 开始可用的语言改进。

无论如何,我向您推荐一个与您的一样复杂(可能更多)但完全免费的解决方案。

如果您定义一个简单的 bool 包装器(可以粗略地替代 C++11 std::true_typestd::false_type )

template <bool B>
struct bool_wrapper
{ static const bool value = B; };

你可以定义你的条件如下

template <typename, typename = bool_wrapper<true> >
struct cond : public bool_wrapper<false>
{ };

template <typename T>
struct cond<T, bool_wrapper<(1 == T::code) || (2 == T::code)> >
: public bool_wrapper<true>
{ };

如果你定义一个enable_if类型特征(与 C++11 相同 std::enable_if )

template <bool, typename = void>
struct enable_if
{ };

template <typename T>
struct enable_if<true, T>
{ typedef T type; };

您可以 SFINAE 启用/禁用您的 foo()功能

template <typename T>
typename enable_if<false == cond<T>::value>::type foo (T const & arg)
{ std::cout << "no static member code or value not 1 and not 2\n"; }

template <typename T>
typename enable_if<true == cond<T>::value>::type foo (T const & arg)
{ std::cout << "static member code and its value is " << T::code << "\n"; }

下面是一个完整的 C++98 示例

#include <iostream>

template <int N> struct A1 { static const int code = N; };
template <int N> struct A2 { static const int code = N; };
// ...
template <int N> struct AN { static const int code = N; };

struct B1{};
struct B2{};
// ...
struct BN{};

template <bool B>
struct bool_wrapper
{ static const bool value = B; };

template <typename, typename = bool_wrapper<true> >
struct cond : public bool_wrapper<false>
{ };

template <typename T>
struct cond<T, bool_wrapper<(1 == T::code) || (2 == T::code)> >
: public bool_wrapper<true>
{ };

template <bool, typename = void>
struct enable_if
{ };

template <typename T>
struct enable_if<true, T>
{ typedef T type; };


template <typename T>
typename enable_if<false == cond<T>::value>::type foo (T const & arg)
{ std::cout << "no static member code or value not 1 and not 2\n"; }

template <typename T>
typename enable_if<true == cond<T>::value>::type foo (T const & arg)
{ std::cout << "static member code and its value is " << T::code << "\n"; }

int main ()
{
foo(A1<0>()); // match the 1st version of foo
foo(A2<1>()); // match the 2nd version of foo
foo(AN<2>()); // match the 2nd version of foo
foo(B1()); // match the 1st version of foo
foo(BN()); // match the 1st version of foo
}

我不知道你使用的 boost 类,但我想你可以修改你的代码(几乎可以像我的无 boost 解决方案一样工作)如下

template <typename, typename = bool_<true> >
struct Condition : public bool_<false>
{ };

template <typename T>
struct Condition<T, bool_<(1 == T::code) || (2 == T::code)> >
: public bool_<true>
{ };

-- 编辑 --

OP 询问

I do not understand how it works for the case A1<0>. The specialization of Condition should be the preferred match, with the 2nd argument expanding to bool_. That class inherits from bool_, so, it should pick the wrong versions of foo. However it works. How is it possible?

嗯...当你写foo(A1<0>()) , 编译器必须理解 cond<A1<0>>::valuetruefalse启用 foo() 的第一个版本或第二个。

所以编译器必须实现cond<A1<0>> .但是没有 cond仅接收类型名的模板类。无论如何,编译器发现

template <typename, typename = bool_wrapper<true> >
struct cond;

使用第二个模板参数的默认值进行匹配。

没有选择,所以没有歧义,所以cond< A<1> >成为cond< A<1>, bool_wrapper<true> >

现在编译器必须在 cond<typename, typename> 的主版本之间进行选择。 (继承自 bool_wrapper<false> 的那个)和特化(继承自 bool_wrapper<true> 的那个)。

cond< A<1>, bool_wrapper<true> >肯定配主版本,还配专业版?如果还匹配特化,编译器必须更喜欢特化。

所以我们需要看看是否cond< A<0>, bool_wrapper<true> >与专业相匹配。

使用 A<0>作为T ,我们有特化成为

cond< A<0>, bool_wrapper<(1 == A<0>::code) || (2 == A<0>::code)> >

也就是

cond< A<0>, bool_wrapper<(1 == 0) || (2 == 0)> >

也就是

cond< A<0>, bool_wrapper<false || false> >

也就是

cond< A<0>, bool_wrapper<false> >

这不匹配 cond< A<0>, bool_wrapper<true> > .

所以 cond< A<0> > , 即 cond< A<0>, bool_wrapper<true> > , 仅匹配 cond<typename, typename> 的主版本, 所以继承自 bool_wrapper<false> .

现在我们可以看看cond< A<1> > .

至于cond< A<0> > , 唯一的模板 cond匹配cond< A<1> >cond<typename, typename>第二个typename使用默认值。

所以 cond< A<1> >cond< A<1>, bool_wrapper<true> > .

但是cond< A<1>, bool_wrapper<true> >仅匹配 cond<typename, typename> 的主要版本还是专业?

我们可以看到使用A<1>作为T ,我们有特化成为

cond< A<1>, bool_wrapper<(1 == A<1>::code) || (2 == A<1>::code)> >

也就是

cond< A<1>, bool_wrapper<(1 == 1) || (2 == 1)> >

也就是

cond< A<1>, bool_wrapper<true || false> >

也就是

cond< A<1>, bool_wrapper<true> >

这匹配cond< A<1>, bool_wrapper<true> > .

因此,对于 cond< A<1> > , 又名 cond< A<1>, bool_wrapper<true> , cond<typename, typename> 的两个版本匹配,所以编译器必须选择特化,所以 cond< A<1> >继承自 bool_wrapper<true> .

关于c++ - 使用 enable_if 仅匹配具有特定静态数据成员且仅具有特定值的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52565407/

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