使用 enable_if 在按值传递与按引用传递之间更改函数声明
Using enable_if to change function declaration between pass by value vs pass by reference
我正在编写一个模板化哈希图。 因为我希望如果模板化类型是基础的,则通过引用传递函数声明。
例如,使用以下声明:
template<typename K,
typename V,
typename Hasher = DEFAULT_HASH_32<K>,
typename Allocator = DEFAULT_MMAP_ALLOC<K, V>>
class my_table {
...
int add(K const & key, V const & val);
};
...
template<typename K, typename V, typename Hasher, typename Allocator>
int
my_table<K, V, Hasher, Allocator>::add(K const & key, V const & val)
我希望能够在传递 K 或 V 作为参考或值之间切换,具体取决于给定类型
的最佳选择。我知道我可能有int add(...)
函数的副本,但我想知道是否有办法只更改声明而不必拥有完全相同函数的副本。
显然,以下伪代码不起作用,但它应该清楚地说明我正在尝试做什么:
#if is_fundemental<K> && is_fundemental<V>
int add(K key, V val);
#elif is_fundemental<K> && !is_fundemental<V>
int add(K key, V const & val);
#elif !is_fundemental<K> && is_fundemental<V>
int add(K const & key, V val);
#else
int add(K const & key, V const & val);
#endif
// then at the functions implementation
#if is_fundemental<K> && is_fundemental<V>
int add(K key, V val) {
#elif is_fundemental<K> && !is_fundemental<V>
int add(K key, V const & val) {
#elif !is_fundemental<K> && is_fundemental<V>
int add(K const & key, V val) {
#else
int add(K const & key, V const & val) {
#endif
谢谢!
编辑:Piotr Skotnicki有一个答案!
不要将 SFINAE 用于更改签名这样简单的事情。请改用一些调整参数类型的基本调用特征:
#include <type_traits>
template <typename K, typename V>
class my_table
{
template <typename T>
using param_type = std::conditional_t<std::is_fundamental_v<T>, T, const T&>;
public:
int add(param_type<K> key, param_type<V> val);
};
template <typename K, typename V>
int my_table<K, V>::add(param_type<K> key, param_type<V> val)
{
return {};
}
演示
下面是别名的 c++11 定义:
template <typename T>
using param_type = typename std::conditional<std::is_fundamental<T>::value
, T
, const T&>::type;
相关文章:
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- 在 const 函数中通过引用和指针返回之间的区别
- 在两台机器之间进行时间戳的最佳c++chrono函数是什么
- 使用.find函数在c++中查找字符和另一个字符之间的大小
- 构造函数和转换运算符之间的重载解析
- C++LinkedList问题.数据类型之间存在冲突?没有匹配的构造函数
- 编译器如何在使用SFINAE的函数和标准函数之间确定两者是否可行
- 为什么 c++(g++) 不允许模板返回类型和函数名称之间有空格?
- 填充上编译器生成的复制构造函数之间的不一致
- 析构函数和'delete'之间的区别
- 为什么不允许成员函数和非成员函数之间的函数重载?
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 如何在"push_*()"和"emplace_*()"函数之间进行选择?
- 内联函数的函数本地静态对象是否在共享对象文件之间共享?
- 派生类(构造函数具有参数)和基类(构造函数缺少参数)之间没有可行的转换
- 在"template"和函数声明之间使用:template<typename trait> using tr = base_trait<trait> void fn(tr::t
- 在 C 和 C++ 中作为函数参数,int **a 和 int a[][] 之间有什么确切的区别
- 定义类模板构造函数的两种方法之间的区别
- 仅具有运算符()的结构和普通函数之间的实际区别
- 可变/非可变模板之间函数类型衰减的不一致性