我希望能够判断传递给函数,方法或类方法的数字参数是否来自硬编码。
所以,例如调用
MyFunc(2);
或
int a = 1;
MyFunc(a);
应该重载函数以允许不同的实现或某种区分方式
void MyFunc(int num)
{
if (isHardcodedNumber(num))
doThis();
else
doThat();
}
这是一个简化版本。理想情况下,我需要一个采用模板参数的解决方案,适用于任何内置数值类型。
这可能吗?
答案 0 :(得分:3)
你无法区分这两种情况。
您的函数只是在堆栈上(或在寄存器中,取决于您的处理器)获取一个值。
无法 知道该值在被推入堆栈或复制到寄存器之前来自何处(当然,除非您传递额外的参数来指示左右)。
答案 1 :(得分:3)
实际上,我可以考虑实现它的极端丑陋的黑客攻击。但请不要......这只是为了学术讨论。
bool isNumber(const char* x){
return isdigit(x[0]);
}
#define MyFunc_t(x) MyFunc(x,#x)
void MyFunc(int x , const char* xStr){
bool isHardcodedNumber = isNumber(xStr);
//do...
}
MyFunc_t(4);
int x = 8;
MyFunc_t(x);
模板专家可能会将其转换为编译时常量,但我不会走得那么远。
但无论如何,请不要在第一时间。
答案 2 :(得分:2)
你可以排序通过重载rvalue引用来做到这一点,尽管这会阻止你拥有一个值版本(因为它变得模棱两可):
#include <iostream>
using namespace std;
void f(int&& f)
{
std::cout << "r-value reference: " << f << '\n';
}
void f(const int& f)
{
std::cout << "value: " << f << '\n';
}
// you can't have void f(int) as it is now ambiguous.
int main()
{
f(1);
int a = 2;
f(a);
// it can be fooled though
f(std::move(a));
return 0;
}
打印:
r-value reference: 1
value: 2
r-value reference: 2
请在此处查看:http://ideone.com/gZoD3m
答案 3 :(得分:2)
好吧,正如其他人所说的那样 - 不建议这样做,但只是为了表明它在某种程度上是可能的,但我不确定它是否适用于所有情况:
首先,您应该知道 - 您可以测试是否在constexpr上下文中调用函数。只需检查其noexcept
属性 - 正如here所述。
所以,你可以测试:
constexpr int f_constexpr(int a)
{
return a;
}
int main(int argc, char* argv[])
{
cout << noexcept(f_constexpr(7)) << endl; // print 1
cout << noexcept(f_constexpr(argc)) << endl; // print 0
}
您从上面的程序获得1
,然后是0
。
不幸的是,在f_constexpr(int)
正文中你总是得到false
- 因为参数a
不被视为const。所以,似乎是错误的方式。
但是...
您可以使用模板标记调度和宏 - 来使某些工作正常:
template <bool isConstexpr>
struct f_impl;
template <>
struct f_impl<false>
{
static int f(int a)
{
cout << "well, I'm not constexpr f()\n";
return a;
}
};
constexpr int f_constexpr(int a)
{
return a;
}
template <>
struct f_impl<true>
{
static constexpr int f(int a)
{
return f_constexpr(a);
}
};
宏定义 - 当然 - 你总是有相同的args:
#define f(a) f_impl<noexcept(f_constexpr(a))>::f(a)
所以,只需检查它是否有效:
int main(int argc, char* argv[]) {
constexpr int a = f(7);
cout << "constexpr was called..." << endl;
int c = f(argc);
cout << "non constexpr was called, I guess..." << endl;
cout << a << endl;
cout << c << endl;
}
和live demo并输出:
constexpr被称为......
好吧,我不是constexpr f()非constexpr被召唤,我猜......
7
1