auto
的模板参数推导函数的返回值”)我正在开发一个由多个类模板组成的通用 C++ 框架 允许结合彼此的专业知识。 由于外部原因,语言版本仅限于 C++14。 在非通用用户代码中使用我的框架最终会导致复杂的模板专业化,例如
MyType<foo<bar, baz, quuz<quz>, zip<zap<zoo>>> myObj{
foo<bar, baz, quuz<quz>, zip<zap<zoo>>{
bar{},
baz{},
quuz<quz>{
quz{}
},
zap<zoo>{
zoo{}
}
}
};
当然,模板参数类型不必等于构造函数参数的类型, 但就我目前的代码而言,这种情况经常发生。 显示的代码只是真实代码的漫画(更多类型/模板), 但这应该足以指出我的问题 (如果您需要一些可编译的示例代码来进行评估,请告诉我):
当我引用所需的所有模板参数时,这会在代码中引起很多噪音, 特别是对于那些必须重复命名的类型。 类型别名 (
using
) 看起来并不是完美的补救措施,因为该示例需要
还有很多这样的。
我检查了模板参数推导的可能性,并且 我了解到 C++14 仅支持函数模板的模板参数推导 (比如经常讨论的
std::make_pair
的例子),但是
类模板参数推导(CTAD)
在 C++17 之前不可用。
使用基于函数的模板参数推导(和“make 函数”), 我可以“简化”上面示例代码右侧的对象初始化表达式, 这会导致类似的事情
MyType<foo<bar, baz, quuz<quz>, zip<zap<zoo>>> myObj = make_obj(
make_foo(
bar{},
baz{},
make_quuz(quz{}),
make_zap(zoo{})
)
);
在可以使用
auto
的上下文中,我什至可以达到简短且富有表现力的代码的目标,例如
auto myObj = make_obj(make_foo(bar{}, baz{}, make_quuz(quz{}), make_zap(zoo{})));
但这似乎仅在某些情况下才可能,例如,
myObj
是局部变量。
我想实现一个框架库,使用户能够创建自己的、非通用的 基于我的模板的课程,但他们不必重复(并记住)所有课程 用于实现其类实现的类型(= 模板特化),如下所示:
class UserType
{
public:
UserType() : m_frameworkImplementation{make_foo(/*...*/)} {}
private:
// This is illegal code, of course. Only to show what I'd like to realize...
auto m_frameworkImplementation;
};
可悲的是,我无法在这里对
auto
做任何事情,而且我无法用 auto
替换 MyType
如果我不将所有模板参数复制到其中。
我还用
decltype
、lambdas和其他东西做了一些徒劳的尝试,但我什至没有获得
关于可能的解决方案的提示(在这里展示任何这些失败的尝试都让人感到尴尬)。
似乎没有办法推断出类模板构造的特殊类型,或者
函数模板推导的专业化的返回值(例如,“make function”),
在需要推导类型来实例化成员变量的类型时。
我忽略了什么?我是否必须等到可以使用 C++17 或 C++20 才能达到预期结果?
C++14 具有自动返回类型推导,因此您可以使用它来“隐藏”您的类型。
#include <utility>
template <typename T>
class UserType
{
public:
UserType(T&& val) : m_frameworkImplementation{std::move(val)} {}
private:
T m_frameworkImplementation;
};
auto make_foo()
{
return UserType<int>(6);
}
int main()
{
auto type = make_foo();
}
用户 IDE 应该仍然能够推断类型,因为
make_foo
和 UserType
都将是模板化代码(并且不能跨越翻译单元边界)。