想象一下这段代码:
#include <iostream>
void PrintInternal() {
std::cout << std::endl;
}
template <typename T, typename...ARGS>
void PrintInternal(const T& head, const ARGS&...rest) {
std::cout << head << " ";
PrintInternal(rest...);
};
template <typename...ARGS>
void PrintInternal(const double& head, const ARGS&...rest) {
std::cout << "DBL!!! " << head << " ";
PrintInternal(rest...);
}
template <typename...ARGS>
void Print(const ARGS&...args) {
PrintInternal(args...);
}
int main() {
Print(1.1, 2, 3.3, 4);
Print(0, 1.1, 2, 3.3, 4);
return 0;
}
首先Print
输出:
DBL !!! 1.1 2 3.3 4
我的期望是,它会输出DBL !!! 3.3之前或没有DBL !!!一点都不但为什么一个???
第二个Print
输出:
0 1.1 2 3.3 4
为什么没有DBL !!!如果我们在第一个例子中有一个输出就像输出一样。
如何实现,对于每个double
,我会输出一些不同而没有部分特化的东西?我想过,简单的重载应该没问题......
链接到cpp.sh以查看编译结果 - &gt; http://cpp.sh/42cz
答案 0 :(得分:6)
查找PrintInternal()
将找到两种类型的函数:
在这种情况下,我们的所有参数都是基本类型,因此没有任何关联的命名空间。这使事情变得更容易。所以当我们开始时:
#include <iostream>
void PrintInternal() { // #1
std::cout << std::endl;
}
template <typename T, typename...ARGS>
void PrintInternal(const T& head, const ARGS&...rest) { // #2
std::cout << head << " ";
PrintInternal(rest...); // <== (*)
};
template <typename...ARGS>
void PrintInternal(const double& head, const ARGS&...rest) { // #3
std::cout << "DBL!!! " << head << " ";
PrintInternal(rest...);
}
对PrintInteral()
的标记呼叫只有两个候选:nullary函数(#1)和它自己(#2)。另一个,PrintInteral()
(#3)更加专业化const double&
尚不可见,所以从未被视为候选人。并不是#2比#3更受欢迎,只是它是唯一的选择。
如果你翻转两个重载的顺序,那么你有一个不同的问题 - 你将无法找到#2!
这为您提供了一些选择:
PrintSingle()
,这样更容易。仅针对最重要的第二个要点引入另一个论点。只是一个伪参数,只是用ADL进行名称查找。这个解决方案有时是必要的,但总是令人困惑:
namespace N {
struct adl { };
void PrintInternal(adl ) {
std::cout << std::endl;
}
template <typename T, typename...ARGS>
void PrintInternal(adl, const T& head, const ARGS&...rest) {
std::cout << head << " ";
PrintInternal(adl{}, rest...);
}
template <typename...ARGS>
void PrintInternal(adl, const double& head, const ARGS&...rest) {
std::cout << "DBL!!! " << head << " ";
PrintInternal(adl{}, rest...);
}
}
template <typename...ARGS>
void Print(const ARGS&...args) {
PrintInternal(N::adl{}, args...);
}
答案 1 :(得分:0)
您有可见性问题,可以通过前瞻性声明来解决:
$(window).load(function(){
var resizeHero = function(){
var hero = $("#hero-fold")
window1 = $(window);
hero.css({
"width": window1.width(),
"height": "auto"
});
if(window1.width() < window1.height())
{
hero.css({
"width": window1.width(),
});
}
};
resizeHero();
$(window).resize(function(){
resizeHero();
});
});
更简单的方法是仅针对简单的打印,并将递归分开,例如:
template <typename...ARGS> void PrintInternal(const double& head, const ARGS&...rest);
template <typename T, typename...ARGS>
void PrintInternal(const T& head, const ARGS&...rest) {
std::cout << head << " ";
PrintInternal(rest...);
}
template <typename...ARGS>
void PrintInternal(const double& head, const ARGS&...rest) {
std::cout << "DBL!!! " << head << " ";
PrintInternal(rest...);
}