【问题标题】:check return type from templated method检查模板化方法的返回类型
【发布时间】:2018-06-28 15:20:02
【问题描述】:

我正在开发 c++11 应用程序:

我有一些模板化的方法:

template <class P, class T>
void copyMemberToDocument(const P &childClass
                          std::string (T::*getter) (void) const) {
   auto member = (childClass.*getter)();
   // ...
}

子类有多重继承,所以我可以有类似的东西:

class A {
public:
  int getA() {return 1;}

class B {
public:
  const char* getB() {return "hello";}

class C : public A, public B {};

所以我可以这样做:

C c;
copyMemberToDocument(c, &B::getB);
copyMemberToDocument(c, &A::getA);

是否有可能知道模板化方法中的返回值是“const char*”还是“int”,以便根据它做不同的事情?

【问题讨论】:

  • 这可能会有所帮助:stackoverflow.com/questions/15911890/…
  • 但该解决方案会让我为每种返回类型拥有一个专门的模板,对吧?
  • 您的copyMemberToDocument 定义中似乎缺少逗号。您还将它限制为返回std::string 的方法,因此不能使用&amp;A::getA&amp;B::getB 调用它
  • 你真的尝试过代码吗?第二个模板参数是返回 std::string 的成员函数。你不能使用不同的返回类型,除非你把它模板化,然后你知道类型

标签: c++ c++11 templates return-type-deduction


【解决方案1】:

正确的实现是:

template <class P, class T>
void copyMemberToDocument(const P childClass, T getter) {
   static_assert(std::is_member_function_pointer<T>::value,
                 "getter is not a member function."); 
   using member_type = decltype((std::declval<P>().*getter)());
   member_type member = (childClass.*getter)();
 }

现在,如果您需要执行不同的代码,根据member_type 的类型,您可以使用函数重载、类特化或c++17 的if constexpr

if constexpr(std::is_same_v<int,member_type>) {
   std::cout<<"I am a int member\n";
}
if constexpr(std::is_same_v<std::string,member_type>) {
   std::cout<<"I am a string member\n";
}

您可能必须使用std::remove_reference

【讨论】:

  • 现在可以询问会员的类型吗?
  • 问它的类型是什么意思。类型是 member_type。如果在调用成员函数之前不需要它,可以使用decltype(member)。
  • 如果 getter 方法可以返回 std::string、int 或 std::pair,我怎么知道“真实”类型。这就是我的意思
  • “知道”是什么意思?您想根据返回的类型执行不同的代码吗?
  • 我给出了一个通用的答案,但你想要实现的伪代码会有所帮助。
【解决方案2】:

你可以使用基本的函数重载

void something(const char*) { /* ... */ }
void something(int)         { /* ... */ }

template <class P, class T>
void copyMemberToDocument(const P &childClass
                          std::string (T::*getter) (void) const) {
   auto member = (childClass.*getter)();
   something(member);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 2020-02-06
    • 1970-01-01
    • 1970-01-01
    • 2016-10-29
    相关资源
    最近更新 更多