C++ 可变模板中的类成员函数

C++ 可变模板中的类成员函数,c++,templates,googletest,gmock,C++,Templates,Googletest,Gmock,我试图编写一个可变函数来生成一个gmock匹配器,它可以同时检查多个属性的零度 // Class with three properties. class Vec3 { public: double x() const; double y() const; double z() const; }; using ::testing::AllOf; using ::testing::Property; Vec3 vec3; // I could do this... EXPECT_

我试图编写一个可变函数来生成一个gmock匹配器,它可以同时检查多个属性的零度

// Class with three properties.
class Vec3 {
 public:
  double x() const;
  double y() const;
  double z() const;
};

using ::testing::AllOf;
using ::testing::Property;

Vec3 vec3;
// I could do this...
EXPECT_THAT(vec3, AllOf(Property(&Vec3::x, Eq(0.0)),
    Property(&Vec3::y, Eq(0.0)), Property(&Vec3::z, Eq(0.0)));

// But I'd want to do something like this...
EXPECT_THAT(vec3, PropertiesAreZero(&Vec3::x, &Vec3::y, &Vec3::z));
我似乎无法在编写生成等效匹配器的变量函数方面取得进展。以下是我一直在尝试的:

template <typename T, typename M, typename P>
Matcher<T> PropertiesAre(M matcher, P(T::*... args)()) {
    return AllOf(Property(args, matcher)...);
};

template <typename T, typename... Others>
Matcher<T> PropertiesAreZero(Others... others) {
    return PropertiesAre(Eq(0.0), others...);
}

Vec3 vec3;
EXPECT_THAT(vec3, PropertiesAreZero(&Vec3::x, &Vec3::y, &Vec3::z));
模板
匹配器属性是(M Matcher,P(T:*…args)(){
返回AllOf(属性(args,matcher)…);
};
模板
匹配器属性为零(其他…其他){
返回属性是(等式(0.0),其他;
}
Vec3-Vec3;
期望(vec3,属性为零(&vec3::x,&vec3::y,&vec3::z));
我得到以下编译错误:

error: type 'P (T::*)()' of function parameter pack does not contain any unexpanded parameter packs
Matcher<T> PropertiesAre(M matcher, P(T::*... args)()) {
                                    ~~~~~~^~~~~~~~~~~
error: pack expansion does not contain any unexpanded parameter packs
  return AllOf(Property(args, matcher)...);
               ~~~~~~~~~~~~~~~~~~~~~~~^
error: no matching function for call to 'PropertiesAre'
          PropertiesAre(Ne(0.0),
          ^~~~~~~~~~~~~
gmock/include/gmock/gmock-matchers.h:5240:60: note: expanded from macro 'EXPECT_THAT'
    ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
                                                           ^~~~~~~
gtest/include/gtest/gtest_pred_impl.h:117:23: note: expanded from macro 'EXPECT_PRED_FORMAT1'
  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
                      ^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:104:17: note: expanded from macro 'GTEST_PRED_FORMAT1_'
  GTEST_ASSERT_(pred_format(#v1, v1), \
                ^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:80:52: note: expanded from macro 'GTEST_ASSERT_'
  if (const ::testing::AssertionResult gtest_ar = (expression)) \
                                                   ^~~~~~~~~~
note: candidate function template not viable: requires 2 arguments, but 4 were provided
Matcher<T> PropertiesAre(M matcher, P(T::*... args)()) {
           ^
error: no matching function for call to 'PropertiesAreZero'
          PropertiesAreZero(
          ^~~~~~~~~~~~~~~~~
gmock/include/gmock/gmock-matchers.h:5240:60: note: expanded from macro 'EXPECT_THAT'
    ::testing::internal::MakePredicateFormatterFromMatcher(matcher), value)
                                                           ^~~~~~~
gtest/include/gtest/gtest_pred_impl.h:117:23: note: expanded from macro 'EXPECT_PRED_FORMAT1'
  GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_)
                      ^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:104:17: note: expanded from macro 'GTEST_PRED_FORMAT1_'
  GTEST_ASSERT_(pred_format(#v1, v1), \
                ^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:80:52: note: expanded from macro 'GTEST_ASSERT_'
  if (const ::testing::AssertionResult gtest_ar = (expression)) \
                                                   ^~~~~~~~~~
note: candidate template ignored: couldn't infer template argument 'T'
Matcher<T> PropertiesAreZero(Others... others) {
           ^
error: no matching function for call to 'PropertiesAreZero'
              PropertiesAreZero(
              ^~~~~~~~~~~~~~~~~
错误:函数参数包的类型“P(T::*)()”不包含任何未展开的参数包
匹配器属性是(M Matcher,P(T:*…args)(){
~~~~~~^~~~~~~~~~~
错误:包扩展不包含任何未扩展的参数包
返回AllOf(属性(args,matcher)…);
~~~~~~~~~~~~~~~~~~~~~~~^
错误:没有用于调用“PropertiesAre”的匹配函数
不动产为(Ne(0.0),
^~~~~~~~~~~~~
gmock/include/gmock/gmock matchers.h:5240:60:注意:从宏“EXPECT\u THAT”展开
::测试::内部::MakePredicateFormatterFromMatcher(matcher),值)
^~~~~~~
gtest/include/gtest/gtest_pred_impl.h:117:23:注意:从宏“EXPECT_pred_FORMAT1”展开
GTEST_PRED_FORMAT1_uu(PRED_format,v1,GTEST_NONFATAL_ufailure)
^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:104:17:注意:从宏“gtest_pred_FORMAT1”展开
GTEST_ASSERT_(pred_格式(#v1,v1)\
^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:80:52:注意:从宏“gtest_ASSERT”展开
if(const::testing::AssertionResult gtest_ar=(表达式))\
^~~~~~~~~~
注意:候选函数模板不可行:需要2个参数,但提供了4个
匹配器属性是(M Matcher,P(T:*…args)(){
^
错误:没有用于调用“PropertiesAreZero”的匹配函数
财产归零(
^~~~~~~~~~~~~~~~~
gmock/include/gmock/gmock matchers.h:5240:60:注意:从宏“EXPECT\u THAT”展开
::测试::内部::MakePredicateFormatterFromMatcher(matcher),值)
^~~~~~~
gtest/include/gtest/gtest_pred_impl.h:117:23:注意:从宏“EXPECT_pred_FORMAT1”展开
GTEST_PRED_FORMAT1_uu(PRED_format,v1,GTEST_NONFATAL_ufailure)
^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:104:17:注意:从宏“gtest_pred_FORMAT1”展开
GTEST_ASSERT_(pred_格式(#v1,v1)\
^~~~~~~~~~~
gtest/include/gtest/gtest_pred_impl.h:80:52:注意:从宏“gtest_ASSERT”展开
if(const::testing::AssertionResult gtest_ar=(表达式))\
^~~~~~~~~~
注意:已忽略候选模板:无法推断模板参数“t”
匹配器属性为零(其他…其他){
^
错误:没有用于调用“PropertiesAreZero”的匹配函数
财产归零(
^~~~~~~~~~~~~~~~~

我真的很感激能在这方面得到任何帮助。我已经面对这一问题整整一天了。

如果手头没有像
这样的定义,要准确地理解这一点是有点困难的,但我想尝试一下你的意图,然后我会试图解释你错在哪里

template<typename R, typename T>
using const_member_ptr = R(T::*)() const;

template<typename T, typename M, typename... R>
Matcher<T> PropertiesAre(M matcher, const_member_ptr<R,T> ...args)
{
    return AllOf<T>(Property(args, matcher)...);
}

template <typename T, typename... R>
Matcher<T> PropertiesAreZero(const_member_ptr<R,T>... others)
{
    return PropertiesAre<T>(Eq(0.0), others...);
}

编译继续。

请提供一个,以便我们可以调试它,而不仅仅是查看您的代码。您的
属性甚至不是可变的,因为它没有模板参数包。
template<typename T>
class Matcher{};

struct Eq
{ Eq(double){} };

template<typename T, typename... X>
Matcher<T> AllOf(X ...x) {}

template<typename P, typename M>
int Property(P p, M m) {}