【发布时间】:2017-06-08 03:50:18
【问题描述】:
我正在尝试从内联 C++ 函数中获取特定类型的行为,但我不确定是否有办法做到这一点。
我希望我的函数接受有符号或无符号 16 位值作为参数,对该值执行操作,然后返回相同类型的值。如果参数的有符号/无符号是不明确的(例如,因为它是一个常量),那么编译器可以只选择有符号的版本。这是一个玩具程序,展示了我第一次尝试获得这种行为:
#include <iostream>
#include <cstdint>
int16_t getValuePlusOne( int16_t x) {return x+1;}
uint16_t getValuePlusOne(uint16_t x) {return x+1;}
using namespace std;
int main(int, char **)
{
int16_t signedVal = -15;
uint16_t unsignedVal = 23;
cout << getValuePlusOne( signedVal) << endl; // works, yay!
cout << getValuePlusOne(unsignedVal) << endl; // works, yay!
cout << getValuePlusOne(1234) << endl; // COMPILE ERROR, ambiguous! D'oh!
return 0;
}
所以这几乎可以工作,但它在 getValuePlusOne(1234) 上出错,因为 1234 是不明确的(它可以是有符号或无符号的)。很公平,但我不希望它这样做。
这是我的第二次尝试:
#include <iostream>
#include <cstdint>
template <typename T> T getValuePlusOne(T val) {return val+1;}
using namespace std;
int main(int, char **)
{
int16_t signedVal = 5;
uint16_t unsignedVal = 5;
cout << getValuePlusOne( signedVal) << endl; // works, yay!
cout << getValuePlusOne(unsignedVal) << endl; // works, yay!
cout << getValuePlusOne(1234) << endl; // works, yay!
uint32_t inappropriateType32 = 54321;
cout << getValuePlusOne(inappropriateType32) << endl; // works, but I want this to be a compile-time error! D'oh!
float inappropriateTypeFloat = 666.0;
cout << getValuePlusOne(inappropriateTypeFloat) << endl; // works, but I want this to be a compile-time error!
return 0;
}
这个版本的工作方式正是我希望它在前三个调用 getValuePlusOne() 时的工作方式——它们编译时没有错误,并且模板机制确保 getValuePlusOne() 的返回类型与其参数类型匹配,并选择一个模棱两可的情况下的默认参数/返回类型。耶!
但是——这个版本还允许用户传入在我的应用程序上下文中没有意义的不适当的值(例如 32 位整数,甚至——gasp——浮点类型),所以我希望编译器将这些调用标记为编译时错误,而此实现不会发生这种情况。
有什么方法可以让我把蛋糕也吃掉吗?
【问题讨论】:
-
请注意,
1234的类型为int。如果你想让getValuePlusOne(1234)工作,那么int x = 1234; getValuePlusOne(x);也可以工作。 -
您可以将函数模板设置为
= delete;以禁用来自您未明确启用的任何类型的调用