Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板推断给我一个通用引用的错误_C++_Templates_C++17 - Fatal编程技术网

C++ 模板推断给我一个通用引用的错误

C++ 模板推断给我一个通用引用的错误,c++,templates,c++17,C++,Templates,C++17,为了真正理解C++17折叠表达式,我为容器编写了一个函数append: #include <iostream> #include <vector> #include <list> // fold expression template<typename T, typename U, template<typename> typename... Args> inline void append_impl(std::vector<T

为了真正理解C++17折叠表达式,我为容器编写了一个函数append:

#include <iostream>
#include <vector>
#include <list>

// fold expression
template<typename T, typename U, template<typename> typename... Args>
inline void append_impl(std::vector<T>& v, Args<U>... args) noexcept
{
  static_assert((std::is_constructible_v<T,U>));
  std::cout << "append_impl version one " << std::endl;
  (v.insert(std::end(v),
            std::begin(args),
            std::end  (args)), ...);
}

//fold expression
template<typename T, typename... Args>
inline void append_impl(std::vector<T>& v, Args&&... args) noexcept
{
  static_assert((std::is_constructible_v<T, Args&&> && ...));
  std::cout << "append_impl version two " << std::endl;
  (v.push_back(std::forward<Args>(args)), ...);
}
// fold expression
template<typename T, typename... Args>
inline void append(std::vector<T>& v, Args&&... args) noexcept
{
  (append_impl(v, args), ...);
}


int main()
{
std::vector<int> a = {1,2};
std::vector<int> b = {3,4};
std::vector<int> c = {5,6};
std::list<int> d = {15,16};

append(a,b,c, std::vector<int>{8,9}, 10, 11, 12, 13, 14, d);


for(const auto& e : a)
{
    std::cout << e << " ";
}
std::cout << std::endl;

return 0;
}
这很好,给我一个结果:

附加\u impl版本1

附加\u impl版本1

附加\u impl版本1

附加\u impl版本2

附加\u impl版本2

附加\u impl版本2

附加\u impl版本2

附加\u impl版本2

附加\u impl版本1

12345689101121314141516

但我有一个问题来自于这段代码:

在append_impl的第一个版本中,args是按副本传递的。我想在Scott Meyers sens中使用通用引用来避免这种情况,但是附加了_implst::vector&v,Args&&。。。args给我一个编译错误。
为什么以及如何避免复制?

您的代码存在以下问题:

你忘了包括在内

您忘记在“附加”中转发:

但是,您有一个问题,即非常量左值引用更适合直接使用Args&&的第二个模板重载,因此您需要添加另一个重载:

template<typename T, typename U, template<typename...> typename... Args>
inline void append_impl(std::vector<T>& v, Args<U>&... args) noexcept 
{
    append_impl(v, std::as_const(args)...);
}
要求包括

通常,您试图识别容器的方式是不保存的。对于所有由模板类构成且不是容器的类型,它都将失败

相反,您可以通过SFINAE在将要使用的容器接口上选择正确的函数重载,即std::beginarg、std::endarg和insert调用。你可以用它来做

或者,您可以为这些表达式的良好格式编写一个类型特征,并为append\u impl使用一个重载,该重载基于检查类型特征的if constexpr选择实现

在C++20中,这将以更简单的方式实现,使用概念


似乎也没有任何理由认为append_impl将Args作为参数包。对于Args,只能使用一个参数调用它。

如果您的代码出现错误,请将该代码及其错误告诉我们。是的,抱歉,完成了。
(append_impl(v, std::forward<Args>(args)), ...);
template<typename T, typename U, template<typename...> typename... Args>
inline void append_impl(std::vector<T>& v, const Args<U>&... args) noexcept

template<typename T, typename U, template<typename...> typename... Args>
inline void append_impl(std::vector<T>& v, Args<U>&&... args) noexcept
template<typename T, typename U, template<typename...> typename... Args>
inline void append_impl(std::vector<T>& v, Args<U>&... args) noexcept 
{
    append_impl(v, std::as_const(args)...);
}