我需要做以下工作。
这是我实际代码的简化版本,但基本上难度相同,即推断出工厂方法的返回类型。
具体来说,我需要DeduceObjectT
的第二个或第三个变体(两个都已注释),而不是第一个,需要FactoryT::ObjectT
typedef。
#include <string>
#include <utility>
#include <memory>
template<class FactoryT>
using DeduceObjectT = typename FactoryT::ObjectT;
//template<class FactoryT>
//using DeduceObjectT = typename decltype(std::declval<FactoryT>().create())::element_type;
//template<class FactoryT>
//using DeduceObjectT = typename std::result_of<decltype(&FactoryT::create)(FactoryT)>::type::element_type;
template<class FactoryT>
struct FactoryUser
{
typedef DeduceObjectT<FactoryT> ObjectT;
};
template<class FactoryUserT>
struct Foo
{
typedef typename FactoryUserT::ObjectT ObjectT;
};
struct StringFactory
{
typedef std::string ObjectT; // want to omit this
std::unique_ptr<std::string> create()
{
return nullptr;
}
Foo<FactoryUser<StringFactory>> t;
};
int main()
{
StringFactory f;
return 0;
}
经过多次尝试后,我仍然遇到错误:无效使用不完整类型'struct StringFactory'&#39;。
我还尝试通过FactoryUser
的默认模板参数推断出类型。
我真的不明白,为什么我得到错误,因为触发所有模板实例化的点就在最后 - 声明数据成员t
的行。
编译器是gcc 4.7.3。使用-std = c ++ 0x -O0
答案 0 :(得分:1)
尝试这样的事情:
template <typename Factory>
struct ProductTypedef
{
typedef typename decltype(std::declval<Factory>().create())::element_type ObjectT;
};
struct StringFactory : public ProductTypedef<StringFactory> // CRTP
{
std::unique_ptr<std::string> create()
{
return nullptr;
}
};
答案 1 :(得分:1)
您可以稍微更改Foo
以使代码正常工作:
#include <string>
#include <utility>
#include <memory>
template<class FactoryT>
using DeduceObjectT = typename FactoryT::ObjectT;
template<class FactoryT>
struct FactoryUser
{
typedef DeduceObjectT<FactoryT> ObjectT;
};
// Provide a way for ObjectType to be specified at the time
// the template is instantiated.
template<class FactoryUserT, typename ObjectType = typename FactoryUserT::ObjectT>
struct Foo
{
typedef ObjectType ObjectT;
};
struct StringFactory
{
std::unique_ptr<std::string> create()
{
return nullptr;
}
Foo<FactoryUser<StringFactory>, std::string> t;
};
int main()
{
StringFactory f;
return 0;
}