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_Lambda_C++11_Type Inference - Fatal编程技术网

C++ 为什么模板参数推断失败?

C++ 为什么模板参数推断失败?,c++,templates,lambda,c++11,type-inference,C++,Templates,Lambda,C++11,Type Inference,我正试图理解这段代码失败的原因: #include <iostream> using namespace std; template <typename Lambda> struct Handler { bool _isCompleted; bool isCompleted() { return _isCompleted; } Lambda _l; Handler(Lambda&& l) : _l(l) {} void ca

我正试图理解这段代码失败的原因:

#include <iostream>

using namespace std;


template <typename Lambda>
struct Handler
{
  bool _isCompleted;

  bool isCompleted() { return _isCompleted; }

  Lambda _l;
  Handler(Lambda&& l) : _l(l) {}

  void call() { _l(this); }
};

int main()
{
  auto l1 = new Handler( [&](decltype(l1) obj )->
{
  obj->_isCompleted = true;
  cout << " is completed?" << obj->isCompleted() << endl;
});
  l1->call();
};

我的理解是,
autoL1
应该解析为
Handler*
,并且lambdaType应该有一个公共函数签名
void(Handler*)
。我不认为上面的例子有任何明显的错误(你知道,除了lambda和handler类型之间的丑陋和稍微病态的循环依赖之外)

类型推断对构造函数不起作用
auto
将推断表达式的类型,是的,但是
new Handler()
需要显式类型。改为编写工厂函数:

// also don't use raw owning pointers
template <typename L>
std::unique_ptr<Handler<L>> make_handler(L lambda) {
    return std::unique_ptr<Handler<L>>(new Handler<L>(lambda));
}

它会很好地工作。

类型推断对构造函数不起作用
auto
将推断表达式的类型,是的,但是
new Handler()
需要显式类型。改为编写工厂函数:

// also don't use raw owning pointers
template <typename L>
std::unique_ptr<Handler<L>> make_handler(L lambda) {
    return std::unique_ptr<Handler<L>>(new Handler<L>(lambda));
}

正如@Cat所说,一个问题是,模板参数推导对构造函数调用不起作用。您始终需要指定模板参数

另一个问题可以通过以下代码片段的叮当声很好地说明:

struct X{
  X(...){}
};

int main(){
  auto l = X([](decltype(l)& o){});
}
输出:

t.cpp:6:26: error: variable 'l' declared with 'auto' type cannot appear in its
      own initializer
  auto l = X([](decltype(l)& o){});
                         ^
1 error generated.
强制性标准报价:

§7.1.6.4[dcl.spec.auto]p3

否则,将从其初始值设定项推断变量的类型。所声明变量的名称不应出现在初始值设定项表达式中。[……]


一个问题是,正如@Cat所说,模板参数推导对于构造函数调用不起作用。您始终需要指定模板参数

另一个问题可以通过以下代码片段的叮当声很好地说明:

struct X{
  X(...){}
};

int main(){
  auto l = X([](decltype(l)& o){});
}
输出:

t.cpp:6:26: error: variable 'l' declared with 'auto' type cannot appear in its
      own initializer
  auto l = X([](decltype(l)& o){});
                         ^
1 error generated.
强制性标准报价:

§7.1.6.4[dcl.spec.auto]p3

否则,将从其初始值设定项推断变量的类型。所声明变量的名称不应出现在初始值设定项表达式中。[……]


你不是在要求你的编译器无中生有地合成一个类型,除了病态循环的自我依赖之外,没有任何关于它的具体信息吗?你不是在要求你的编译器无中生有地合成一个类型,除了病态循环的自我依赖之外,没有任何关于它的具体信息吗自力更生?但这不是唯一的问题。另一个是
auto
声明的变量不能在它们自己的初始值设定项中使用。我同意,问题似乎是在l1初始化中使用l1。即使在解决了这些问题之后,我也得到了更多的错误模板参数推导对构造函数是有效的,但只是推导构造函数参数,而不是被构造的类型。不过,这不是唯一的问题。另一个是
auto
声明的变量不能在它们自己的初始值设定项中使用。我同意,问题似乎是在l1初始化中使用l1。即使在解决了这些问题之后,我也得到了更多的错误模板参数推导对构造函数是有效的,但它只是用来推导构造函数参数,而不是被构造的类型。我早该知道的。谢谢是的,在叮当声面前,他脸色苍白。我早该知道的。谢谢