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

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

例如,带有以下声明:

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作为参考或作为值之间进行切换,这取决于给定类型的最佳选择。

I know that I could have duplicates of the int add(...) function but I am wondering if there is a way to only change the declaration without having to have copies of the exact same function.

显然,以下伪代码不起作用,但是应该可以清楚地了解我要执行的操作:

#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

谢谢!

评论
  • 香诗翠
    香诗翠 回复

    不要将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 {};
    }
    

    DEMO