C++具有ADL(Argument Dependent Lookup),正如其名称所描述的那样,函数的上下文(命名空间)可以从(任何)参数的上下文(命名空间)隐含.
fun(a); // if the type of a is in namespace ns deduce ns::f if available
Run Code Online (Sandbox Code Playgroud)
我的问题是,通过某种技术是否也可以反过来?反过来我的意思是如果可以从被调用函数的上下文推导出上下文(命名空间).某种"功能依赖查找"(FDL).假代码:
ns::fun(a); // deduce ns::a if available
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚这样做的方法.对于enum用于编码功能选项的s来说,这种限制尤其令人讨厌.我想知道是否有一种模拟此功能的技术(C++ 11也可以).假代码:
ns::fun(Saturday, Tuesday); // Saturday/Tuesday are enum values in namespace ns;
Run Code Online (Sandbox Code Playgroud)
特别是如果有enums 的解决方法.
此代码说明了此问题:
namespace longname{
class A{};
void fun(A const& a){}
A global_a;
enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday};
void gun(Days d1, Days d2){}
}
int main(){
longname::A a;
fun(a); // cool, longname::fun(a) not necessary, fun is deduced from context …Run Code Online (Sandbox Code Playgroud) 提出的问题: 在模板中键入条件
非常相似,但原始问题并未得到完全回答。
#include "stdafx.h"
#include <type_traits>
class AA {
public:
double a;
double Plus(AA &b) {
return a + b.a;
}
};
template<class T> double doit(T &t) {
if (std::is_same<T, AA>::value)
return t.Plus(t);
else
return t + t;
}
int _tmain(int argc, _TCHAR* argv[])
{
double a;
AA aa;
doit(a);
doit(aa);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这不会编译,我也没有期望。这样的事情可能吗?基于模板值,我希望一些代码可以编译,而其他则不需要。在这里,“ double”没有称为“ Plus”的方法,而“ AA”类不会覆盖“ +”运算符。考虑操作的细微语义时,操作符重载并不总是可取的,因此我正在寻找一种替代方法。我宁愿进行#ifdef的工作(如参考问题中所述的进行真正的条件编译),但要基于模板值。
我有一个用A模板化的类,该类Scalar可以是实数值或复数值。它具有realPart应该返回数字的实部的方法。如果Scalar为实值,则应返回原始标量,并且.real()为复杂类型。
写作时
#include <complex>
#include <iostream>
template<class Scalar>
class A {
public:
A (const Scalar z):
z_(z)
{
}
Scalar realPart()
{
return z_.real();
}
private:
Scalar z_;
};
int main() {
A<std::complex<double>> z0((1.0, 2.0));
std::cout << z0.realPart() << std::endl; // check
A<double> z1(1.0);
std::cout << z1.realPart() << std::endl; // mööp
}
Run Code Online (Sandbox Code Playgroud)
编译器会z1.realPart()因为double不知道而抱怨.real()。
如何.real()在编译时进行防护?
当我们做...
template <typename T>
void foo(T x)
{
if (is_fundamental<T>::value)
{
...
} else
{
...
}
}
Run Code Online (Sandbox Code Playgroud)
我认为if声明(以及is_fundamental<T>::value)在运行时进行评估,是吗?
如果是,是否有办法在编译时进行此评估?我希望有类似......
template <primitive_typename T>
void foo(T x)
{
...
}
template <noPrimitive_typename T>
void foo(T x)
{
...
}
Run Code Online (Sandbox Code Playgroud)
一种解决方案是重载每种可能的原始类型,但它并不是一个令人满意的解决方案,因为它需要多次复制基本类型的代码.有没有办法用一个类型名称来引用所有原语?