首页 > 解决方案 > c++:强制将 std::string 强制转换为 string_view 而不是模板

问题描述

我有以下类声明:

class MyClass {
public :
    template <typename StringContainer>
    explicit MyClass(const StringContainer&)
    {
        std::cout << "String container ctor" << std::endl;
    }

    explicit MyClass(std::string_view)
    {
        std::cout << "string_view ctor" << std::endl;
    }
};

模板化的构造函数版本被实现来处理带有 std::string 的 stl 容器。对于下面的片段,我想调用string_viewctor 但由于某种原因使用了模板版本。

int main() {
    std::string tmp("a");
    MyClass test(tmp);

    return 0;
}

与ctorstd::string一起使用的正确投射方式是什么?std::string_view

标签: c++

解决方案


选择您的模板构造函数是因为它std::stringstd::string_view构造函数更匹配。 StringContainer被推断为std::string,对MyClass(const StringContainer&)进行精确匹配tmp,而MyClass(std::string_view)需要从std::string到的隐式转换std::string_view

如果你想std::string_view调用构造函数,你可以显式地进行转换,例如:

int main() {
    std::string tmp("a");
    MyClass test(std::string_view{tmp});

    return 0;
}

演示

否则,您可以仅为 添加另一个构造函数std::string,例如:

class MyClass {
public :
    template <typename StringContainer>
    explicit MyClass(const StringContainer&)
    {
        std::cout << "String container ctor" << std::endl;
    }

    explicit MyClass(const std::string&)
    {
        std::cout << "String ctor" << std::endl;
    }

    explicit MyClass(std::string_view)
    {
        std::cout << "string_view ctor" << std::endl;
    }
};

int main() {
    std::string tmp("a");
    MyClass test(tmp); // calls MyClass(const std::string&)

    return 0;
}

演示

或者,您可以尝试使用 SFINAE 使模板构造函数与任何不匹配的std::string或不匹配std::string_view(我的 SFINAE-fu 不太好,所以我不会尝试在这里提供示例)。

或者,您可以使模板仅与元素的实际容器匹配,这样std::string传入 astd::string只能与 匹配std::string_view,例如:

class MyClass {
public :
    template < template <typename, typename...> typename StringContainer >
    explicit MyClass(const StringContainer<std::string>&)
    {
        std::cout << "String container ctor" << std::endl;
    }

    explicit MyClass(std::string_view)
    {
        std::cout << "string_view ctor" << std::endl;
    }
};

int main() {
    std::string tmp("a");
    MyClass test(tmp); // calls MyClass(std::string_view)

    std::vector<std::string> vec;
    MyClass test2(vec); // calls MyClass(const StringContainer&)

    return 0;
}

演示


推荐阅读