我有以下代码:
$(".track_it").click(function () {
console.log($(this).data("location"));
});
输出:
#include <iostream>
#include <cassert>
#include <utility>
struct real_type {
struct real_category{};
typedef real_category num_category;
};
struct imag_type: public real_type {
struct imag_category{};
typedef imag_category num_category;
};
template<class number_type>
struct number_traits {
typedef typename number_type::num_category num_category;
};
void print_num(double x, double y, typename real_type::num_category) {
assert(y==0);
std::cout<<"real num - x: "<<x<<std::endl;
}
void print_num(double x, double y, typename imag_type::num_category) {
std::cout<<"imag num - x: "<<x<<", y: "<<y<<std::endl;
}
template<int Y=0, typename num_type = typename std::conditional<Y==0, real_type, imag_type>::type >
void print_num(double x) {
typename number_traits<num_type>::num_category num_category;
print_num(x, Y, num_category);
}
int main() {
print_num(1);
print_num<3>(2);
return 0;
}
我对这段代码的行为并不满意。可以看出,我将虚数值约束为整数。另外,我必须使用尾随real num - x: 1
imag num - x: 2, y: 3
来调用print_num的虚构变体,这也不是优雅的。
这种结构的原因是,为了推断出正确的类别标签,我必须检查<>
的值。但是这种检查只能在模板参数列表中进行。
所以我的问题是:是否有可能在保持此标记调度结构(即保持函数Y
和void print_num(..., typename real_type::num_category)
不变的情况下)定义调度函数,如void print_num(..., typename imag_type::num_category)
这意味着(?)通过检查void print_num(double x, double y=0)
是否以某种方式推断出正确的num_category。
我知道我可以通过在y==0
函数中使用if(y==0)\*then call print_num with real_category tag*\else \*call with imag_category tag*\
进行检查来解决此问题。这会使number_traits类过时(我不想要)。即我想在模板参数列表中做出这个决定。这可能吗?我想不是(?)
更新
基于答案我重写了代码:
void print_num(double x, double y=0)
输出:
#include <iostream>
#include <cassert>
#include <utility>
struct real_type {
struct real_category{};
typedef real_category num_category;
struct real_number{ double x; };
typedef real_number num;
num num_x;
};
struct imag_type: public real_type {
struct imag_category{};
typedef imag_category num_category;
struct imag_number{ double x; double y; };
typedef imag_number num;
num num_xy;
};
template<class number_type>
struct number_traits {
typedef typename number_type::num_category num_category;
};
void print_num(real_type r, typename real_type::num_category) {
std::cout<<"real num - x: "<<r.num_x.x<<std::endl;
}
void print_num(imag_type i, typename imag_type::num_category) {
std::cout<<"imag num - x: "<<i.num_xy.x<<", y: "<<i.num_xy.y<<std::endl;
}
template<typename num_type>
void print_num(num_type i) {
typename number_traits<num_type>::num_category num_category;
print_num(i, num_category);
}
int main() {
real_type r_type;
r_type.num_x.x = 1.1;
imag_type i_type;
i_type.num_xy.x = 2.1;
i_type.num_xy.y = 3.2;
print_num(r_type);
print_num(i_type);
return 0;
}
它现在正在工作。如果此代码现在与tag-dispatch概念一致,则不完全确定
答案 0 :(得分:0)
我认为你最好在运行时检查虚部而不是编译时间。以下是使用std::complex
#include <complex>
#include <iostream>
#include <limits>
#include <sstream>
template<class T>
auto print(std::complex<T> const& c)
{
std::stringstream sstr;
if (std::abs(c.imag()) < std::numeric_limits<T>::epsilon()) {
sstr << c.real();
} else {
sstr << c;
}
return sstr.str();
}
int main()
{
auto const c1 = std::complex{1.0};
auto const c2 = std::complex{2.0, 3.0};
std::cout << print(c1) << "\n"; // prints: 1
std::cout << print(c2) << "\n"; // prints: (2, 3)
}