感谢阅读这个问题。
代码在这里。版本 C++17
#include <iostream>
#include <memory>
#include <queue>
template<typename TValue>
[[maybe_unused]]
constexpr auto t1(const std::queue<TValue> &value) -> void {
std::queue<TValue> temp = value;
while (!temp.empty()) {
std::cout << temp.front() << std::endl;
temp.pop();
}
}
template<typename TValue>
constexpr auto t1(const TValue &nm) -> void {
std::cout << nm << std::endl;
}
template<typename TValue>
constexpr auto t1(const std::shared_ptr<TValue> &nm) -> void {
t1<TValue>(*nm);
}
int main(int argc, char **argv) {
std::shared_ptr<const std::string> s_ptr = std::make_shared<const std::string>("test");
t1(s_ptr);
return 0;
}
我尝试使用shared_ptr更改模板,例如:
template<typename TValue>
constexpr auto t1(const std::shared_ptr<TValue> &nm) -> void {
TValue temp = *nm;
t1<TValue>(temp);
}
但它犯了同样的错误。
然后我尝试获取“TValue”类型:
template<typename TValue>
constexpr auto t1(const std::shared_ptr<TValue> &nm) -> void {
if constexpr (std::is_same_v<TValue, const std::string>){
static_assert(false, "??");
}
t1<TValue>(*nm);
}
static_assert 被触发。这意味着 'TValue' 只是 'const std::string'。
不小心,我像这样删除了
<TValue>
:
template<typename TValue>
constexpr auto t1(const std::shared_ptr<TValue> &nm) -> void {
t1(*nm);
}
或者:
template<typename TValue>
constexpr auto t1(const std::shared_ptr<TValue> &nm) -> void {
t1<std::remove_cv_t<TValue>>(*nm);
}
它有效。
那么当有
<TValue>
时,为什么模板要将 const std::string 转换为 std::queue ???
谢谢你的回答。
问题在于您显式提供了模板参数
TValue
,这会导致 std::deque<const std::string>
的实例化。
std::deque<T>
需要一个非常量、非易失性 T
,正如失败的静态断言所示:
错误:静态断言失败:
必须具有非常量、非易失性std::deque
value_type
您可以写
t1(*nm)
来代替。
这里的区别在于 std::deque<const std::string>
永远不会被实例化。
相反,替换为 t1(std::deque)
将会失败,因为 *nm
是 const std::string
并且 TValue
中的 std::deque<TValue>
无法从 const std::string
推导出来。
template<typename TValue>
constexpr auto t1(const std::shared_ptr<TValue> &nm) -> void {
t1(*nm); // OK
}