从返回函数

时间:2017-02-22 16:50:09

标签: c++ c++11 c++14

希望你们能帮忙解决这个问题: 我有以下函数应该返回一个对象Foo,在这种情况下具有特定的类型:

Foo<int,bool> make_my_foo_object() {
  return make_foo(10);
}

在我的Foo课程中我有:

template <class A, class B>
  struct Foo {
    Foo(A aa): a(aa) {}
    Foo(B bb): b(bb) {}
    A a;
    B b;
  };

然后,在我的make_foo函数中,我有:

template<typename A, class B>
    Foo<A,B> make_foo(A a) {
        return Foo<A,B>(a); // this should call the Foo(A) ctor
    };

我知道这是不可能的,因为在这个简单的实现中没有办法可以从make_foo的返回类型推断B

make_my_foo_object在这种情况下没有多大意义,但整个想法是处理模板参数,因为它们被错过而无法推断出来。

我要避免的是在{{1>}函数中指定 return make_foo <int, bool>(10); 中的类型。

你们认为有可能解决这个问题吗?或者这是不行的!

任何帮助或信息将不胜感激。 感谢。

3 个答案:

答案 0 :(得分:1)

template<class...Ts>
struct make_something_t {
  std::tuple<Ts...> data;
  template<class T, std::size_t...Is>
  T make(std::index_sequence<Is...>) && {
    return T( std::get<Is>(std::move(data))... );
  }
  template<class T>
  operator T()&&{
    return std::move(*this).template make<T>(std::make_index_sequence<sizeof...(Ts)>{});
  }
};
template<class...Ts>
make_something_t<Ts...> make_something( Ts&&...ts ) {
  return {std::forward_as_tuple(std::forward<Ts>(ts)...)};
}

live example

make_something(args...)没有做任何事情。相反,你可以使用它来构造(几乎)任何东西,它使用args...来构造你从中构造的任何类型。

这可能不是一个好主意,但它会从你构造的对象中推断出你所构造的对象的类型。

答案 1 :(得分:1)

  

我要避免的是在返回make_foo(10)中指定类型;在make_my_foo_object函数中。

这样的东西可能适合你(C ++ 14中的最小的工作示例):

template <class A, class B>
struct Foo {
    Foo(A aa): a(aa) {}
    Foo(B bb): b(bb) {}
    A a;
    B b;
};

template<typename A, class B>
Foo<A,B> make_foo(A a) {
    return Foo<A,B>(a);
}

struct W {
    template<typename A, typename B>
    operator Foo<A, B>() {
        return make_foo<A, B>(10);
    }
};

auto make_my_foo_object() {
    return W{};
}

int main() {
    Foo<int, bool> foo1 = make_my_foo_object();
    Foo<int, char> foo2 = make_my_foo_object();
}

模板参数由W中的运算符推导出:

template<typename A, typename B>
operator Foo<A, B>() {
    return make_foo<A, B>(10);
}

如果您将其标记为C ++ 14,则允许auto返回类型,其余部分将完成 根据要求(如果我的请求得到了正确的话)make_my_foo_object不再有模板参数,那就是它不是函数模板。

答案 2 :(得分:0)

如果你唯一关心的是避免重复硬编码类型的参数,你可以给它们这样的名字:

template <typename A=int, typename B=bool>
Foo<A,B> make_my_foo_object() {
  return make_foo<A,B>(10);
}

也就是说,关于用于A和B的类型的决定只是从返回类型移动到模板参数列表。