使用 enable_if 在按值传递与按引用传递之间更改函数声明

Using enable_if to change function declaration between pass by value vs pass by reference

本文关键字:之间 函数 声明 按引用传递 enable if 按值传递 使用      更新时间:2023-10-16

我正在编写一个模板化哈希图。 因为我希望如果模板化类型是基础的,则通过引用传递函数声明。

例如,使用以下声明:

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;
相关文章: