c++ 有条件地允许向 Package 对象提供分配器

2w2cym1i  于 2023-07-01  发布在  其他
关注(0)|答案(1)|浏览(128)

我正在创建一个容器,它可以在它为其成员使用的字符串类型上模板化,无论它是拥有或非拥有字符串(std::string vs std::string_view)。对于非拥有字符串的情况,我不能提供分配器,因此我必须说服编译器编写一个不接受分配器的构造函数。这是我目前的方法,但我还有很多问题要解决:
演示

#include <iostream>
#include <string_view>
#include <memory>
#include <string>

template <typename T>
concept uses_allocator_general = requires {
    typename T::allocator_type;
};

template <typename StringType = std::string>
struct URL {
    using allocator_type = std::conditional_t<uses_allocator_general<StringType>,
        typename StringType::allocator_type, void>;

    URL(allocator_type allocator = {})
        : mystr{allocator}
    { }

    StringType mystr;
};

int main() {
    URL myurl;

    URL<std::string_view> myurl_view;
}

1.这不会编译,因为StringType::allocator_typestd::conditional_t之前被计算。我必须使用某种间接或SFINAE来有条件地检索typedef。
1.即使它要编译,我可以有条件地删除参数吗?即使它接受默认参数?我觉得这不可能。我有什么选择?
1.也许有一个更优雅的解决方案,这个问题,我不知道?

axr492tv

axr492tv1#

您可以分别为这两种情况提供两个约束构造函数

template <typename T>
concept uses_allocator_general = requires {
    typename T::allocator_type;
};

template <typename StringType = std::string>
struct URL {
    template<uses_allocator_general AllocStringType = StringType>
    URL(AllocStringType::allocator_type allocator = {})
        : mystr{allocator}
    { }

    URL() requires (!uses_allocator_general<StringType>) = default;

    StringType mystr;
};

Demo

相关问题