C++ 我可以避免在一系列函数调用中使用模板消歧器吗?
我有一个模板生成器/工厂类,它生成C++ 我可以避免在一系列函数调用中使用模板消歧器吗?,c++,c++11,templates,C++,C++11,Templates,我有一个模板生成器/工厂类,它生成Foo类型的对象,其中make()方法是一个模板方法,如下所示: template<typename T1> class FooMaker { template<typename T2> Foo make(...) { ... } }; 我想在上面构建Foo的每一行上都需要模板关键字。一般来说,我在每个FooMaker对象上都有许多对make()的调用,因此在创建工厂时添加少量代码就可以了 显然,我可以使用一个隐藏模板细节的宏来
Foo
类型的对象,其中make()
方法是一个模板方法,如下所示:
template<typename T1>
class FooMaker
{
template<typename T2>
Foo make(...) { ... }
};
我想在上面构建Foo
的每一行上都需要模板
关键字。一般来说,我在每个FooMaker
对象上都有许多对make()
的调用,因此在创建工厂时添加少量代码就可以了
显然,我可以使用一个隐藏模板
细节的宏来实现这一点,但是否有一个好的非宏解决方案1
1我可以将
T1
和T2
移动到相同的级别-通过使它们都成为类模板参数或函数模板参数,但是前者需要为每个新类型的T2
指定一个不同的生成器,后者意味着在每个make
调用中冗余指定相同的T1
。这是一个很大的原因,因为它是一个非成员函数,而不是std::tuple
的成员。从该模式中汲取灵感,您可以创建一个非成员make_foo
:
template <typename T2, typename T1, typename... Args>
Foo make_foo( FooMaker<T1>& maker, Args&& ... args ) {
return maker.template make<T2>(std::forward<Args>(args)...);
}
模板
Foo make_Foo(FooMaker&maker,Args&;Args){
return maker.template make(std::forward(args)…);
}
然后像这样使用它:
auto maker = ...; // some code to construct the builder
Foo foo1 = make_foo<Type1>(maker, ...);
Foo foo2 = make_foo<Type2>(maker, ...);
// etc...
auto-maker=…;//构造生成器的一些代码
Foo foo1=make_Foo(制造商,…);
Foo Foo 2=制造者;
//等等。。。
您可以确保推导出T2
。为此,你需要一个以某种方式提供信息的论点。这可能是一种简单的标记类型
template<typename T>
struct tag { using type = T; };
template<typename T1>
class FooMaker
{
template<typename T2>
Foo make_internal(...) { ... }
public:
template<typename Tag>
Foo make(Tag, ...)
{ return make_internal<Tag::type>(...); }
};
auto maker = ...; // some code to construct the builder
Foo foo1 = maker.make(tag<Type1>{}, ...);
Foo foo2 = maker.make(tag<Type2>{}, ...);
// etc...
模板
结构标记{using type=T;};
模板
职业美食家
{
模板
Foo make_internal(…){…}
公众:
模板
Foo make(标签…)
{返回make_internal(…);}
};
自动生成器=…;//构造生成器的一些代码
Foo foo1=maker.make(标记{},…);
Foo foo2=maker.make(标记{},…);
//等等。。。
或者枚举与traits类型组合,或者您可以简单地使用指针传入类型:
template<typename T1>
class FooMaker
{
public:
template<typename T2>
Foo make(T2*, ...);
};
auto maker = ...; // some code to construct the builder
Foo foo1 = maker.make((Type1*)0, ...);
Foo foo2 = maker.make((Type2*)0, ...);
// etc...
模板
职业美食家
{
公众:
模板
Foo-make(T2*,…);
};
自动生成器=…;//构造生成器的一些代码
Foo foo1=maker.make((Type1*)0,…);
Foo foo2=maker.make((Type2*)0;
//等等。。。
尽管可以说,这并不十分优雅。如果
decltype(maker)
和Type1
都不是依赖类型,我相信你可以编写maker.make(…)代码>。不过,我不确定它的确切规则。@JustinType1
始终是一个函数。但是,decltype(maker)
独立意味着什么?这是否取决于T1的性质?有时T1
是一个计划(非模板类),有时是一个模板类(但我可能会改变这个)。您可以使make
成为一个独立函数,该函数将Maker
作为一个参数,就像std::tuple
getter一样。只有当Maker
的类型不依赖时,您才能省略模板,这意味着它不直接或间接依赖任何模板参数。(Type1
对此不重要。)依赖类型只存在于模板定义中。@BeeOnRope完全正确。谢谢!这是否可以扩展到变量,而不是template make(…)
我有template make()
其中func\u t
是一个函数typedef?@BeeOnRope在这种情况下,你不会传入functorF
(可能是lambda)吗?也许你应该举个例子(或另一篇文章)。不,它总是一个普通函数,从来不是lambda或其他有状态的东西,比如std::function
,所以我使用了模板函数参数特性,没有任何东西作为参数传递,但模板参数只是“直接调用”,例如,typedef void(*func_t)(int);模板调用_f(/*无参数!*/){f(42);}
。你是对的,尽管这已经足够不同了,我也许应该提出一个新问题。
template<typename T1>
class FooMaker
{
public:
template<typename T2>
Foo make(T2*, ...);
};
auto maker = ...; // some code to construct the builder
Foo foo1 = maker.make((Type1*)0, ...);
Foo foo2 = maker.make((Type2*)0, ...);
// etc...