我有一个StrongType<>
类强制在PoD上强类型:
template <typename T, typename TAG>
class StrongType {
private:
std::string mName;
T mValue;
public:
explicit StrongType(std::string n) : mName(n), mValue() {}
explicit StrongType(std::string n, T v)
: mName(n), mValue(std::move(v)) {
}
const T &value() const { return mValue; }
std::string name() const { return mName; }
};
我有一个保持StrongType
元组的类,需要返回一个非强类型的元组(实际上它应该调用一个非强类型参数的函数):
struct aTag {};
struct bTag {};
struct cTag {};
using aType = utils::StrongType<int, aTag>;
using bType = utils::StrongType<std::string, bTag>;
using cType = utils::StrongType<int, cTag>;
int main()
{
aType a("a", 2);
bType b("b", std::string {"b"});
cType c("c", 10);
AdvTuple<aType,bType,cType> t(a,b,c);
//auto nt = t.getTuple();
//std::cout << std::tuple_size<decltype(nt)>() << "\n";
//std::cout << std::get<0>(nt) << "\n";
//nt.call([](aType ra, bType rb, cType rc) {
//});
return 0;
}
这是我做的实现,但它没有编译:
#include <tuple>
template <typename ...T>
class AdvTuple {
private:
std::tuple<T...> aTuple;
public:
explicit AdvTuple(T... ts)
: aTuple(std::make_tuple(ts...)) {
}
template <int i>
decltype(std::get<i>(aTuple).value()) get() const {
return std::get<i>(aTuple).value();
}
template <int N = 0, typename ...TA, std::enable_if<N < sizeof...(TA)> >
auto getImpl(std::tuple<TA...> t) {
return std::tuple_cat(std::make_tuple(std::get<N>(t)), getImpl<N+1>(t));
};
template <typename ...Q>
std::tuple<Q...> getTuple() const {
return getImpl<0>(aTuple);
}
};
这是来自编译器的消息(mac上的clang):
In file included from
/Users/happycactus/Documents/Progetti/Experiments/tupletraits/main.cpp:3:
/Users/happycactus/Documents/Progetti/Experiments/tupletraits/tupletypes.h:32:16: error: no matching member function for call to 'getImpl'
return getImpl<0>(aTuple);
^~~~~~~~~~
/Users/happycactus/Documents/Progetti/Experiments/tupletraits/main.cpp:25:17: note: in instantiation of function template specialization 'AdvTuple<utils::StrongType<int, aTag>, utils::StrongType<std::__1::basic_string<char>, bTag>, utils::StrongType<int, cTag> >::getTuple<>' requested here
auto nt = t.getTuple();
^
/Users/happycactus/Documents/Progetti/Experiments/tupletraits/tupletypes.h:26:10: note: candidate template ignored: couldn't infer template argument ''
auto getImpl(std::tuple<TA...> t) {
^
1 error generated.
1)如何解决?
2)如何使用推导出的PoD类型的call()
/ lambda
实现function<>
函数?即使非StrongTyped
也可以。
我可以使用C ++ 11和14。
答案 0 :(得分:1)
如果我理解你想要什么,你需要std::make_index_sequence
和std::index_sequence
。
我的意思是...而不是递归getImpl()
,您可以使用包扩展,如下所示
template <std::size_t ... Is>
auto getTuple (std::index_sequence<Is...> const &) const
{ return std::make_tuple(std::get<Is>(aTuple).value()...); }
auto getTuple () const
{ return getTuple(std::make_index_sequence<sizeof...(T)>{}); }
您可以将private
作为第一个getTuple()
(收到std::index_sequence
的那个)。
关于call()
,我不清楚你想要什么。但我想你想要call()
AdvTuple
方法接收可调用的value()
方法并用std::make_index_sequence
调用它。
再次使用std::index_sequence
/ template <typename F, std::size_t ... Is>
auto call (F f, std::index_sequence<Is...> const &) const
{ return f(std::get<Is>(aTuple).value()...); }
template <typename F>
auto call(F f) const
{ return call(f, std::make_index_sequence<sizeof...(Ts)>{}); }
技巧,
private
第一个可以是#include <tuple>
#include <string>
#include <iostream>
#include <type_traits>
template <typename T, typename>
class StrongType
{
private:
std::string mName;
T mValue;
public:
explicit StrongType (std::string n) : mName{std::move(n)}, mValue{}
{ }
template <typename U>
explicit StrongType (std::string n, U v)
: mName{std::move(n)}, mValue{std::forward<U>(v)}
{ }
T const & value () const
{ return mValue; }
std::string const & name () const
{ return mName; }
};
template <typename ... Ts>
class AdvTuple
{
private:
std::tuple<Ts...> aTuple;
template <std::size_t ... Is>
auto getTuple (std::index_sequence<Is...> const &) const
{ return std::make_tuple(std::get<Is>(aTuple).value()...); }
template <typename F, std::size_t ... Is>
auto call (F f, std::index_sequence<Is...> const &) const
{ return f(std::get<Is>(aTuple).value()...); }
public:
template <typename ... Us>
explicit AdvTuple (Us && ... us)
: aTuple{std::make_tuple(std::forward<Us>(us)...)}
{ }
template <std::size_t i>
auto get() const
{ return std::get<i>(aTuple).value(); }
auto getTuple () const
{ return getTuple(std::make_index_sequence<sizeof...(Ts)>{}); }
template <typename F>
auto call(F f) const
{ return call(f, std::make_index_sequence<sizeof...(Ts)>{}); }
};
struct aTag {};
struct bTag {};
struct cTag {};
using aType = StrongType<int, aTag>;
using bType = StrongType<std::string, bTag>;
using cType = StrongType<int, cTag>;
int main ()
{
aType a("a", 2);
bType b("b", std::string {"b"});
cType c("c", 10);
AdvTuple<aType,bType,cType> t(a,b,c);
auto nt = t.getTuple();
std::cout << std::tuple_size<decltype(nt)>() << "\n";
std::cout << std::get<0>(nt) << "\n";
t.call([](int, std::string, int){ std::cout << "Lambda!" << std::endl; });
return 0;
}
。
以下是完整的C ++ 14编译示例
python myscript.py filename