我可以使用带有多个参数的赋值运算符构造吗?

时间:2017-09-29 14:37:01

标签: c++

问题可能听起来很复杂,所以这是一个例子:

std::string s = "1984"; // This calls constructor, not copy assignment

现在std::string具有带有多个参数的构造函数,例如count和char值。 有没有办法在不明确调用它的情况下使用该构造函数?

我不能使用正常构造的原因是我想使用函数的返回值来构造一个非特定容器用户提供,只要该容器具有构造函数获取2个迭代器(不会打扰我的函数的用户来存储返回value并调用构造函数)。

下面是另一个代码的具体示例,其中函数的单个返回值可以触发构造函数调用,但IDK如何使用多个返回值执行此操作。

std::pair<const char*,const char*> last3_iter(const std::string s){
    assert(s.size()>3);
    return std::pair{s.data()+s.size()-3, s.data()+s.size()};
}

const char* last3_ptr(const std::string s){
    assert(s.size()>3);
    return s.data()+s.size()-3;
}

int main()
{
    {
    std::string s_ptr = last3_ptr("0123456789");
    std::cout << s_ptr << std::endl; 
    }
    {
    // Is it possible to rewrite last3_iter so 
    // that assignment operator does equivalent to this code?
    auto range = last3_iter("0123456789");
    std::string s_iter(range.first, range.second);
    std::cout << s_iter << std::endl; 
    }
}

2 个答案:

答案 0 :(得分:2)

您可以使用std::apply,但有点尴尬:

struct X
{
    X(int, int);
};

auto get_params() -> std::tuple<int, int> { return {10, 20}; }
X x = std::apply([](int a, int b) { return X{a, b}; },
                 get_params());

您可以通过创建一个简单的实用程序功能来隐藏它:

template <class T, class... Args>
auto apply_to_ctor(std::tuple<Args...> tp_args) -> T
{
    return std::apply([](Args... largs) { return T{largs...}; },
                      tp_args);
}

然后用作:

X x2 = apply_to_ctor<X>(get_params());

为简洁起见,我省略了使用完美转发。你需要这样做。此外,您可能希望提供重载以接受std::pair。这只是基本的想法。你必须改进它。

答案 1 :(得分:1)

不符合您目前的设计。而不是将参数返回给构造函数来调用,为什么不返回对象本身呢?你得到了复制elision(和C ++ 17之前的RVO),所以它没有性能损失(在最坏的情况下它是一个移动)。

我不确定你的设计是什么,但也许你可以这样做:

template<typename T>
T last3_iter(const T& container) {
    assert(std::size(container) > 3);
    return T(std::next(std::begin(container), std::size(container) - 3), std::end(container));
}

然后这样称呼它:

auto s_iter = last3_iter("0123456789"s);

这适用于大多数(如果不是全部)容器。