【发布时间】:2014-08-13 17:06:03
【问题描述】:
我需要做以下工作。
这是我的实际代码的精简版,但难度基本相同,即推断工厂方法的返回类型。
具体来说,我需要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’”。
我还尝试通过 FactoryUser 的默认模板参数推断类型。
我真的不明白,考虑到触发所有模板实例化的点位于末尾——声明数据成员 t 的行,为什么会出现错误。
编译器是 gcc 4.7.3。与 -std=c++0x -O0
【问题讨论】:
-
请注意,我能够使用 Visual Studio 2013 编译第三个变体。一位朋友也能够使用 clang 3.4.1 和 gcc 4.9 编译第三个变体。
-
删除了我的答案,因为你是正确的,它充其量只是一个近似值。另外,请注意,如果您想看到它在那里工作,我们使用this online compiler 来测试第 3 个变体。如您所述,使用 g++4.7 确实会为第 3 个变体产生编译器错误。
-
@PeterClark 我看到第三个变体(带有 result_of)也可以使用 gcc 4.8.1 编译
标签: c++ templates gcc decltype