gpt4 book ai didi

C++ 模板 : correct way to return a new type

转载 作者:太空狗 更新时间:2023-10-29 20:51:44 24 4
gpt4 key购买 nike

抱歉,标题太笼统了,但我无法聚焦问题。

我有一个模板化的类方法,它接受一个参数包并提供一个新类型作为返回,以隐藏实现的细节。更具体地说,该类处理 SQLite 查询,该方法调用 sqlite3_prepare() 以在执行查询之前准备语句。

class Table {
...
template <typename ...Ts>
class PreparedStatement { ... };

template <typename ...Ts>
PreparedStatement<Ts...> prepare(std::tuple<Ts...> tuple) {
// do something
return PreparedStatement<Ts...> ( ... );
}

这适用于“普通”类型,但当参数声明为 const 时会出现问题:

const Field<int> fld = createField<int>("name");
...
PreparedStatement<decltype(fld)> s = prepare(make_tuple(fld));

错误如下:

no match for 'operator =' (operand types are PreparedStatenent<const Field<int>> and PreparedStatement<Field<int>>

我怀疑问题出在我的函数声明中,有没有办法解决这个问题并使函数更“优雅”?

注意:我知道我可以通过手动声明 s 变量来解决这个问题,但我怀疑该方法是如何实现的。


正如许多人所问,这里有一个例子:

#include <tuple>

template <typename T>
struct Field {
};

class Table {
public:
template <typename ...Ts>
class PreparedStatement {
public:
PreparedStatement() {};
};

template <typename ...Ts>
PreparedStatement<Ts...> prepare(std::tuple<Ts...> tuple) {
// do something
return PreparedStatement<Ts...> ( );
}
};


int main()
{
Field<int> fld;
Table t;

Table::PreparedStatement<decltype(fld)> p;
p = t.prepare(std::make_tuple(fld));

// here comes the problem
const Field<int> f2;
Table::PreparedStatement<decltype(f2)> p2;

p2 = t.prepare(std::make_tuple(f2));

return 0;
}

这是编译器的输出

main.cpp: In function 'int main()': main.cpp:35:39: error: no match for 'operator=' (operand types are 'Table::PreparedStatement >' and 'Table::PreparedStatement >') p2 = t.prepare(std::make_tuple(f2)); ^ main.cpp:10:10: note: candidate: constexpr Table::PreparedStatement >& Table::PreparedStatement >::operator=(const Table::PreparedStatement >&) class PreparedStatement { ^~~~~~~~~~~~~~~~~ main.cpp:10:10: note: no known conversion for argument 1 from 'Table::PreparedStatement >' to 'const Table::PreparedStatement >&' main.cpp:10:10: note: candidate: constexpr Table::PreparedStatement >& Table::PreparedStatement

::operator=(Table::PreparedStatement >&&) main.cpp:10:10: note: no known conversion for argument 1 from 'Table::PreparedStatement >' to 'Table::PreparedStatement >&&'

更新正如许多人指出的那样,我可以使用 auto 来推断类型,但在某些情况下 auto 实际上无法使用。一个是,例如,如果我需要在类上下文中声明语句。所以假设 auto 由于某种原因被禁止。没有其他可用的解决方案吗?请参阅上面的更新代码。

最佳答案

cppreference.com make_tuple告诉我们:

template< class... Types >
tuple<VTypes...> make_tuple( Types&&... args );

For each Ti in Types..., the corresponding type Vi in Vtypes... is std::decay<Ti>::type unless application of std::decay results in std::reference_wrapper<X> for some type X, in which case the deduced type is X&.

同时 std::decay ,除其他事项外,删除 cv 限定符。所以你的类型将是 no PreparedStatement<const Field<int>> ,但是PreparedStatement<Field<int>> .

您可以使用 auto ,正如 manni66 所建议的那样,以避免此类问题。

auto s = prepare(make_tuple(fld));

关于C++ 模板 : correct way to return a new type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48621516/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com