在模板参数的函数中使用一个命名空间或另一个命名空间
Use one namespace or another in function of a template parameter
我想在某些情况下使用std::pow
(从cmath
(的实现,而在其他情况下,我想使用myspace::pow
。
namespace myspace
{
template <typename T>
T pow(T val, unsigned exp)
{
if (exp == 0) return 1;
return val*pow(val,exp-1);
}
}
不同的事例由模板参数确定。
template <typename T>
void myFunction()
{
auto val = pow(2.1,3);
/* ... */
}
如果T == double
,我希望用std::pow
计算val
。如果T == mydouble
,我希望用myspace::pow
计算val
。现在,我有很多像auto val = pow(2.1,3);
这样的行,我想避免检查每行代码的T
类型。
struct mydouble { /* ... */ };
myFunction<double>(); // uses std::pow
myFunction<mydouble>(); // uses myspace::pow
我一直在为此摸不着头脑,但我找不到解决方案。有什么建议吗?
我可以建议几种解决方案。
类调度程序 (C++11(
只需实现一个函子,该函子根据其模板化类型选择正确的实现:
template <typename T>
struct PowerAdapter {
auto operator()(const T& arg, const T& exp) const {
return std::pow(arg, exp);
}
};
template <>
struct PowerAdapter<myspace::MyDouble> {
auto operator()(const myspace::MyDouble& arg, unsigned exp) const {
return myspace::pow(arg, exp);
}
};
您可以按如下方式使用它:
template <typename T>
void myFunction(const T& t) {
using Pow = PowerAdapter<T>;
auto val = Pow{}(t, t);
// ...
}
完整的代码示例
依赖于参数的查找 (C++98(
如果您的类MyDouble
位于pow
的同一命名空间中,则可以使用以下C++规则:
除了通常的非限定名称查找所考虑的范围和命名空间之外,还在其参数的命名空间中查找函数名称。
所以代码:
template <typename T>
void myFunction(const T& t) {
pow(t, 12);
}
将根据T
的命名空间选择合适的pow
。 请注意,如果出现double
,则需要从全局命名空间中的math.h
中选择pow
(非限定名称查找(。
完整的代码示例
我个人不喜欢这种方法,因为它隐藏了选择机制,而且更难扩展。
if constexpr
(C++17(
您可以在编译时选择合适的分支。 将选择逻辑包装到适当的函数(或函子(中。像这样:
template <typename T, typename U>
auto PowerAdapter(const T& val, const U& exp) {
if constexpr (std::is_same_v<T, myspace::MyDouble>) {
return myspace::pow(val, exp);
} else {
return std::pow(val, exp);
}
}
完整的代码示例
使用依赖于参数的查找,您可以轻松实现此目的
namespace ns
{
template <typename T>
auto pow(T val, unsigned exp)
{
using std::pow;
std::cout << __FUNCTION__ << 'n';
return pow(val, exp);
}
}
struct mydouble
{
double d;
};
mydouble pow(mydouble val, unsigned exp)
{
std::cout << __FUNCTION__ << 'n';
return val;
}
int main()
{
ns::pow(mydouble{ 3.14 }, 2); // runs pow
ns::pow(4, 2); // runs std::pow
}
相关文章:
- '使用命名空间{嵌套在另一个命名空间中的某个命名空间}"
- 使用另一个命名空间中的函数C++
- 使用命名空间在另一个".cpp"文件中定义
- 如何使用另一个项目命名空间?
- 使用匿名命名空间中的函数或另一个文件中的静态函数不应该出错吗?
- 在模板参数的函数中使用一个命名空间或另一个命名空间
- 是否有一个很好的方法可以在C 11中打印出像JSON一样的Trie结构(仅迭代解决方案)的扁平命名空间
- C++另一个命名空间中函数的 ADL
- 如何在另一个名称空间内从另一个命名空间内明确专业化功能模板
- 我可以在标头中将一个命名空间"import"到另一个命名空间中吗?
- 为什么主可执行文件和 dlopen 加载的共享库共享命名空间静态变量的一个副本?
- 是否可以将一个命名空间类 #include 到另一个命名空间中
- 从另一个命名空间访问标准命名空间数据成员
- 为什么我不能在标头中只定义一个非常量 gloabal 变量?如果我使用命名空间,为什么我必须声明它"extern"?
- 另一个命名空间和 CRTP 中的模板友元函数
- 如何使 clang 格式将所有详细信息命名空间缩进一个
- 是否可以编写一个C .dll库来导出在命名空间和类中编写的方法
- 在C API中定义了一个类型,如何将其与命名空间中的C++类相关联
- 在命名空间中放入一个标准的纯C头#include指令可以吗
- 依赖于参数的查找在来自另一个命名空间的别名类型上意外行为