我有模板类 Reader
template<typename T>
class Reader{
typedef T type;
};
特殊实现(派生类)具有带签名的方法
T read(IStream&,任意数量的参数,可能为零)
即类 IntegerReader
公共(public)函数:
template <typename T>
class IntegerReader : public Reader<T>{
public:
T read(IStream& stream);
T read(IStream& stream, T min, T max);
T read(IStream& stream, T min, T max, std::string name);
}
现在我想创建一个包装器,它允许我创建另一个阅读器,并调用带有参数的阅读器。
我已经试过了:
template <typename T, typename... Args>
class ParametrizedReader : public Reader<typename T::type> {
T reader;
Args... args;
ParametrizedReader(T reader, Args... args):reader(reader), args(args){
}
typename T::type read(IStream& stream){
return reader.read(args..., stream);
}
};
testlib/readerWrapper.hpp:7:6: error: expected unqualified-id before ‘...’ token
testlib/readerWrapper.hpp: In constructor ‘ParametrizedReader<T, Args>::ParametrizedReader(T, Args ...)’:
testlib/readerWrapper.hpp:8:61: error: class ‘ParametrizedReader<T, Args>’ does not have any field named ‘args’
testlib/readerWrapper.hpp: In member function ‘typename T::type ParametrizedReader<T, Args>::read(IStream&)’:
testlib/readerWrapper.hpp:12:22: error: ‘args’ was not declared in this scope
这个:
template <typename T, typename... Args>
class ParametrizedReader : public Reader<typename T::type> {
std::function<T()> lambda;
ParametrizedReader(T reader, Args... args){
lambda = [=](IStream& stream){
reader.read(stream, args...);
};
}
typename T::type read(IStream& stream){
return lambda(stream);
}
};
testlib/readerWrapper.hpp:9:24: error: parameter packs not expanded with ‘...’:
testlib/readerWrapper.hpp:9:24: note: ‘args’
testlib/readerWrapper.hpp:9:28: error: expansion pattern ‘args’ contains no argument packs
还有这个:
template <typename T, typename... Args>
class ParametrizedReader : public Reader<typename T::type> {
std::function<T()> lambda;
ParametrizedReader(T reader, Args... args){
lambda = [reader, args...](IStream& stream){
reader.read(stream, args...);
};
}
typename T::type read(IStream& stream){
return lambda(stream);
}
};
testlib/readerWrapper.hpp:8:25: error: expected ‘,’ before ‘...’ token
testlib/readerWrapper.hpp:8:25: error: expected identifier before ‘...’ token
testlib/readerWrapper.hpp:8:28: error: parameter packs not expanded with ‘...’:
testlib/readerWrapper.hpp:8:28: note: ‘args’
g++-4.7给出的编译错误
虽然我不确定第一个示例是否正确并且是否应该编译,但我相信第二个和第三个应该。
我找到了 this bug , 这似乎不是固定的。
是否有解决方法,我怎样才能做我想做的事?
最佳答案
您可以通过将参数绑定(bind)到 lambda 而不是捕获它们来解决此问题。
ParametrizedReader(T reader, Args... args){
lambda = std::bind(
[=](IStream& stream, Args... as){
reader.read(stream, as...);
}, args...);
}
虽然您可能想按照@Alexandre 所说的去做,而不是在确切的参数类型上参数化类模板:
template <typename T>
class ParametrizedReader : public Reader<typename T::type> {
std::function<T()> lambda;
template<typename... Args>
ParametrizedReader(T reader, Args... args){
lambda = std::bind(
[=](IStream& stream, Args... as){
reader.read(stream, as...);
}, args...);
}
// ...
};
(注意:未经测试。)
也可能有效的是将 std::bind
放在第二个代码段中,然后像您的第二个或第三个解决方案一样尝试,这次使用可变函数模板。也许它有效,谁知道呢。
关于c++ - 创建类的可变包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12753651/