C++可变参数模板函数调用应用了什么模式匹配(如果有)
What pattern matching (if any) is applied for C++ variadic template function invocation?
我只是天真地写了这个:
#include <stdio.h>
template< class... Args >
auto format_for( Args... args, int last_arg )
-> char const*
{
// using Specifier = char const [3];
// static Specifier const s[] = { {'%', 'f'+(0*args), ' '}..., {'%', 'f', 0} };
return reinterpret_cast<char const*>( "" );
}
auto main() -> int
{
printf( "'%s'n", format_for( 5, 2, 1 ) );
}
它使Visual C++ 2015 update 1崩溃,ICE(内部编译器错误),并且g ++ 5.1.0认为该函数仅接受一个参数,可能是由于无法匹配此模板参数后忽略Args
:
C:\my\forums\so\081> cl printf.cpp/Feb打印f.cppprintf.cpp(14): 致命错误 C1001: 编译器中发生内部错误。(编译器文件 'F:\DD\VCtools\Compiler\cxxfe\SL\P1\cxx\DyMto.c',第 6771 行) 要变通解决此问题,请尝试简化或更改上面列出的位置附近的程序。请在可视C++上选择技术支持命令 "帮助"菜单,或打开技术支持帮助文件以获取更多信息C:\my\forums\so\081> g++ printf.cppprintf.cpp: 在函数 'int main()' 中:printf.cpp:14:43:错误:调用"format_for(int, int, int)"没有匹配函数 printf( "'%s'", format_for( 5, 2, 1 ) ); ^printf.cpp:4:6:注意:候选人:模板<类...Args> const char* format_for(Args ..., int) auto format_for( args... args, int last_arg ) ^printf.cpp:4:6:注意:模板参数推导/替换失败:printf.cpp:14:43:注意:候选人期望 1 个参数,提供 3 个参数 printf( "'%s'", format_for( 5, 2, 1 ) ); ^C:\my\forums\so\081> _类...Args>
所以
为什么以上不能用 g++ 编译?
如何表达意图(希望从代码中可以明显看出)?
更一般地说,匹配可变参数模板函数声明调用的规则是什么?
Args
出现在非推导上下文中。在这种情况下,这使得它被推断为空包。
如果你想提取最后一个参数,但保持通常的演绎规则,你可以编写一个简单的助手:
template <typename U>
constexpr U&& last(U&& u) {return std::forward<U>(u);}
template <typename U, typename... T>
constexpr decltype(auto) last(U&&, T&&... t) {return last(std::forward<T>(t)...);}
演示。
更一般地说,匹配可变参数模板函数声明调用的规则是什么?
这些非常冗长,但未尾随的函数参数包通常会被推导出为空的函数参数包或产生演绎失败。
在您的特定情况下,请尝试index_sequence
template <class... Args, std::size_t... indices>
auto format_for( std::index_sequence<indices...>, Args... args )
{
auto tup = std::forward_as_tuple(std::forward<Args>(args)...);
using Specifier = char const [3];
static Specifier const s[] = { {'%', (char)('f'+(0*std::get<indices>(tup))), ' '}..., {'%', 'f', 0} };
int last_arg = std::get<sizeof...(Args)-1>(tup);
return s;
}
template <class... Args>
auto format_for( Args&&... args ) {
return format_for(std::make_index_sequence<sizeof...(Args)-1>{},
std::forward<Args>(args)...);
}
。并希望编译器优化良好 - 演示 2。或者走上厚脸皮的道路:
template <class... Args, std::size_t... indices>
auto format_for( std::index_sequence<indices...>, Args... args )
{
using Specifier = char const [3];
static Specifier const s[] = {
{'%', (char)(indices == sizeof...(Args)-1?
'f' : 'f'+(0*args)), ' '}... };
int last_arg = last(args...); // As before
return s;
}
template <class... Args>
auto format_for( Args&&... args ) {
return format_for(std::make_index_sequence<sizeof...(Args)>{},
std::forward<Args>(args)...);
}
演示 3.
相关文章:
- 模式匹配文本并提取C++中的数据
- 如何在CLIPS中优化不同模板事实之间的模式匹配
- Flex Lexer 模式匹配句子分隔符/标点符号作为 URL 路径部分
- Haskell中用多态性替换条件的等效模式是什么?
- 最简单的事件设计模式是什么
- C++中的模式匹配
- 模式匹配函数的时间测量无法正常工作
- 从C 中的函数中动态分配的缓冲区返回的最佳模式是什么?
- 解析 HTTP 的摘要式身份验证的正确正则表达式模式是什么?
- C++向量的模式匹配
- 打开文件的正确模式是什么,以便 seekp() 的工作方式与在默认模式下打开的文件相同
- 从.cpp文件中提取与模式匹配的"if"块
- 在某些情况下,通配符模式匹配失败
- 如何使用C++模板魔术来对类型进行模式匹配
- 使用 std::regex_search 获取与模式匹配的所有文件和文件夹
- 这种模式是什么意思?新建(&条目[num_entries])项目;
- 在 c++-17 中特化的模式匹配中 lambda 的拆分函数签名
- 解释器和中介器的设计模式有什么区别
- DNA模式匹配中最快的算法是什么
- C++可变参数模板函数调用应用了什么模式匹配(如果有)