基本上问题可以用这个例子来概括:
template <typename ...Us>
void foo(Us...) { std::cout << "A\n"; }
template <typename ...Us>
void foo(Us..., int) { std::cout << "B\n"; }
int main(){
foo(1,2,3);
}
Run Code Online (Sandbox Code Playgroud)
这称为第一个foo(打印A).我怎么能让它拨打第二个foo?
如果这使用了非变量模板,或者"int"是第一个参数,那么重载规则将调用正确的函数.也就是说,特定类型(int)是比模板更好的匹配,因此它将调用第二个foo.但显然,变量模板的情况并非如此?当变量模板不是最后一个参数时,有没有办法重载变量模板?
我正在尝试编译以下代码:
template <typename T, int N> void foo( const T (&array)[N]) {}
template <typename T> static int args_fwd_(T const &t) { foo(t); return 0; }
template<class ...Us> void mycall(Us... args) {
int xs[] = { args_fwd_(args)... };
}
int main(void) {
int b[4];
mycall(b);
}
Run Code Online (Sandbox Code Playgroud)
该mycall函数使用可变参数模板,然后转发到args_fwd_函数以foo在每个参数上调用函数.
这适用于大多数参数类型(假设我有适当定义的foo函数).但是当我尝试传递C风格的数组(int b[4])时,它变成了一个指针,然后它找不到foo需要数组(而不是指针)的模板化函数.gcc 4.9.3的错误如下:
error: no matching function for call to ‘foo(int* const&)’
note: candidate is:
note: template<class T, int N> void foo(const …Run Code Online (Sandbox Code Playgroud) 假设我有以下代码:
volatile char array[4];
array[0] = 1;
Run Code Online (Sandbox Code Playgroud)
现在,理想情况下,编译器会将其转换为8位存储指令,以便在内存中只修改一个字节.但是,将它转换为读/修改/写可以自由吗?例如,处理此问题的〜等效方法如下:
int32 *temp = (int*)array;
*temp = (*temp & 0xFFFFFF00) | 1;
Run Code Online (Sandbox Code Playgroud)
问题显然是后一种实现将覆盖数组中的其他3个字节.在单线程应用程序中,这是等效的,但不是在多线程的情况下.
那么编译器允许编译第一个实现与第二个相同吗?