【问题标题】:Using enable_if to change function declaration between pass by value vs pass by reference使用 enable_if 在按值传递与按引用传递之间更改函数声明
【发布时间】:2020-09-10 15:22:41
【问题描述】:

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

例如使用以下声明:

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 有答案!

【问题讨论】:

    标签: c++ c++11 enable-if


    【解决方案1】:

    不要将 SFINAE 用于更改签名这样简单的事情。相反,使用一些基本的 call-traits 来调整参数类型:

    #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


    这是别名的 定义:

    template <typename T>
    using param_type = typename std::conditional<std::is_fundamental<T>::value
                                               , T
                                               , const T&>::type;
    

    【讨论】:

    • 这适用于 c++17(谢谢,这比我想的要优雅 100%)。有没有办法用你知道的 c++11 做到这一点?
    • 是否有使用 const T& 而不是 T const& 的原因?
    • @Noah 没有区别。只是风格。
    猜你喜欢
    • 1970-01-01
    • 2013-04-12
    • 2023-03-02
    • 2012-07-03
    • 1970-01-01
    • 2016-10-22
    • 2011-05-08
    相关资源
    最近更新 更多