c++ - 具有多个转换的模板参数推导
问题描述
我正在尝试编写一个泛型函数,其参数包含模板类型的多个转换,例如:
#include <iostream>
#include <string>
#include <type_traits>
template< typename _T_ >
void foo
(
const std::basic_string< typename std::remove_cv< typename std::remove_extent< _T_ >::type >::type > & str
)
{
std::cout << str << std::endl;
}
int main( void )
{
foo< char const [ 3 ] >( "abc" ); // OK
foo( "abc" ); // Cannot deduce template argument
return 0;
}
不幸的是,编译器无法推断出正确的类型。
使用最新版本的 Clang、GCC 和 MSVC 进行测试。
有趣的是,编译器似乎能够通过一种转换进行推断:
const std::basic_string< typename std::remove_extent< _T_ >::type > & str
显然,上面的例子失败了,因为const
,因此需要remove_cv
after remove_extent
。
这是预期的吗,有什么方法可以实现吗?
解决方案
包含qualified-id的复杂名称是C++ 中的非推导上下文。在
foo< char const [ 3 ] >( "abc" );
您提供模板参数T
。在
foo( "abc" );
T
不能推导出模板参数(函数参数与模板参数是分开的,因此T
不会从 推导出来"abc"
)。
一种解决方案是先推导出模板参数,然后basic_string
在参数为 a 时构造const CharT*
:
template <class CharT>
void foo(const std::basic_string<CharT>& string)
{
// ...
}
template <class CharT>
void foo(const CharT* p)
{
std::basic_string<CharT> s{p};
foo(s);
}
另一种解决方案是简单地依靠类模板参数推导来处理这两种情况:
template <class Arg>
void foo(Arg&& arg)
{
std::basic_string s{std::forward<Arg>(arg)};
// ...
}
推荐阅读
- python - 如何使用for循环绘制直方图和条形图并将它们一起显示?
- tibco - 在配置文件 Tibco BW6 中使用环境参数
- android - 通过 Firebase 身份验证使用登录时出现延迟
- javascript - 纹理 Alpha 背景在 Three.js 中未正确显示
- c# - 我怎样才能减慢我的 for 循环,以便我可以看到颜色?
- factorial - 为什么不出现访问冲突?
- makefile - 使用 Makefile 依赖项
- amazon-web-services - 通过 AWS CDK 重新使用现有 CloudFront 分配
- python-3.x - 检查值是否在列表中,如果无效则标记它
- javascript - 如何使用单个按钮打开和关闭 div