首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >我可以使用多个参数的赋值运算符构造吗?

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

Stack Overflow用户
提问于 2017-09-29 22:37:01
回答 2查看 49关注 0票数 2

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

代码语言:javascript
运行
复制
std::string s = "1984"; // This calls constructor, not copy assignment

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

我不能使用普通构造的原因是,我想使用函数的返回值来构造用户提供的非特定容器,只要该容器具有接受2个迭代器的构造函数(而不必麻烦函数的用户存储返回值和调用构造函数)。

下面是另一个代码的具体示例,其中一个函数的单个返回值可以触发构造函数调用,但IDK如何使用多个返回值来实现这一点。

代码语言:javascript
运行
复制
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; 
    }
}
EN

回答 2

Stack Overflow用户

发布于 2017-09-29 23:35:32

您可以使用std::apply,但它有点笨拙:

代码语言:javascript
运行
复制
struct X
{
    X(int, int);
};

auto get_params() -> std::tuple<int, int> { return {10, 20}; }
代码语言:javascript
运行
复制
X x = std::apply([](int a, int b) { return X{a, b}; },
                 get_params());

您可以通过创建一个简单的实用函数来隐藏以下内容,从而使其变得用户友好:

代码语言:javascript
运行
复制
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);
}

然后按如下方式使用:

代码语言:javascript
运行
复制
X x2 = apply_to_ctor<X>(get_params());

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

票数 2
EN

Stack Overflow用户

发布于 2017-09-29 23:24:54

不是用你目前的设计。与其将参数返回给构造函数进行调用,为什么不返回对象本身呢?你得到了拷贝省略(和C++17之前的RVO ),所以它没有性能损失(在最坏的情况下这是一个移动)。

我不知道你在想什么设计,但也许你可以这样做:

代码语言:javascript
运行
复制
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));
}

然后这样叫它:

代码语言:javascript
运行
复制
auto s_iter = last3_iter("0123456789"s);

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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46491183

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档