我正在尝试使用函数模板(或其他一些模板化的结构)来模拟一个函数,而无需对参数或返回表达式进行隐式转换。最有效的方法是什么?
理想情况下,我正在尝试提出一种易于隐藏在模板或宏后面,具有不错的错误消息并且不会造成运行时损失的方法。
这旨在作为元编程练习;我不会在生产代码中这样做。
下面的函数func1
需要两个longs
并将它们加在一起,照常执行转换。
long func1(long a, long b) {
return a + b;
}
我想以和只能是sfunc
的方式进行定义,a
并在编译时检查表达式是否确实具有指示的类型,而无需插入隐式转换。b
long
return
为了具体起见,到目前为止,我已经尝试了几种方法来实现,而现在已经到了。
防止转换的一种方法(仅适用于自变量)是使用带有已删除实现的函数模板,以及对自变量组合进行专门化处理的函数模板。
template <class L1, class L2>
long func2(L1 a, L2 b) = delete;
template<>
long func2(long a, long b) {
return a + b;
}
也可以用来enable_if
完成相同的事情。
template <class L1, class L2>
std::enable_if_t<
std::is_same<L1, long>::value && std::is_same<L2, long>::value
, long> func3(L1 a, L2 b) {
return a + b;
}
但是,我无法弄清楚如何合并一个关于返回类型的断言,而不会使自己付出复制或搬家的代价,或者需要做复杂的事情来剥夺CV资格和参考性。
// doesn't work, unnecessary copy
template <class L1, class L2>
std::enable_if_t<
std::is_same<L1,long>::value && std::is_same<L2,long>::value,
long> func4(L1 a, L2 b) {
auto out = a + b;
static_assert(std::is_same<decltype(out), long>::value);
return out;
}
但是,我可以将函数体移到lambda中,然后使用static_assert
s列出我想要的所有条件。我有点担心这种方法会出乎意料。
template <class L1, class L2>
long func5(L1 a, L2 b) {
static auto wrapped = [&](){
return a + b;
};
static_assert(std::is_same<decltype(a), long>::value);
static_assert(std::is_same<decltype(b), long>::value);
static_assert(std::is_same<decltype(wrapped()), long>::value);
return wrapped();
}
可能有很多方法可以做到这一点。这是一个 我认为没有理由检查所有这些情况。您想对const-volatile限定符做什么?允许还是不允许?
#include <type_traits>
#include <iostream>
template<typename Long>
Long func1(Long a, Long b) {
static_assert(std::is_same_v<Long, long>);
return a + b;
}
int main()
{
long a = 1;
const long b = 2;
const long &c = a;
std::cout << func1(c,b) << std::endl;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句