我有一个模板函数,该函数根据其参数的类型T
生成对象。看起来像
template<typename T>
container<T> foo(T t)
{
return container<T> { item<T>{t} };
}
其中container
是一个模板类,其中包含另一个模板类item
。
我为operator+
实现了container<T>
,以便可以添加具有相同基础类型T
的容器。
现在我要使以下行有效
auto sum = foo("abc") + foo(std::string("def")); // type mismatch
换句话说,我希望foo
在看到container<const char *>
时生成一个std::string
,反之亦然。
我当然可以像这样显式地使foo
超载
container<const char *> foo(std::string str)
{
return container<const char *> { item<const char *> { str.c_str() } };
}
但是我有很多功能,例如foo
,我真的不想为每个功能写一个重载版本。
这是一个开放设计问题。任何解决方案,建议或解决方法均受到欢迎和赞赏。非常感谢。
答案 0 :(得分:2)
我建议使用模板类型别名:
template <typename T> using bar = std::conditional_t<std::is_same_v<T, const char *>, std::string, T>;
然后您的功能将变为:
template<typename T>
container<bar<T>> foo(T t)
{
return container<bar<T>> { item<bar<T>>{t} };
}
答案 1 :(得分:1)
如果您考虑一下,您寻求的行为似乎更具体
container<T>
或container<std::string>
,而不是foo()
及其兄弟姐妹。因此,我想一种实现目标的方法是至少在operator +
情况下使container<std::string>
重载,这样不仅可以添加相同元素类型的容器,还可以添加任何包含以下内容的容器:可以转换为T
(或仅std::string
)到container<T>
(或仅container<std::string>
)的元素类型。例如,与此类似的东西:
template <typename U>
container<std::string> operator +(container<std::string> a, const container<U>& b)
{
a.insert(end(a), begin(b), end(b));
return a;
}
答案 2 :(得分:-1)
auto sum = foo("abc"s) + foo(std::string("def"));
// ^ here
并添加一个字母:
{{1}}