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_Argument Dependent Lookup_Cereal - Fatal编程技术网

C++ 模板替换在依赖参数的查找(或解决方法)之前发生的任何方式

C++ 模板替换在依赖参数的查找(或解决方法)之前发生的任何方式,c++,templates,argument-dependent-lookup,cereal,C++,Templates,Argument Dependent Lookup,Cereal,我想这个问题的基本前提是,我正在尝试使用enable_if和参数相关查找(ADL),但我不确定这是否可行。我明白了 模板参数推导发生在函数模板名称查找(可能涉及参数相关查找)之后、模板参数替换(可能涉及SFINAE)和重载解析之前 所以我想这是行不通的,但本着学习的精神,我想把这个问题提出来 下面是我试图实现的一个例子: #include <iostream> namespace lib1 { template <typename T> void archive

我想这个问题的基本前提是,我正在尝试使用
enable_if
和参数相关查找(ADL),但我不确定这是否可行。我明白了

模板参数推导发生在函数模板名称查找(可能涉及参数相关查找)之后、模板参数替换(可能涉及SFINAE)和重载解析之前

所以我想这是行不通的,但本着学习的精神,我想把这个问题提出来

下面是我试图实现的一个例子:

#include <iostream>

namespace lib1 {
  template <typename T>
  void archive(T & t)
  {
    serialize(t);
  }
}

namespace lib2 {
struct VectorInt {
  int x;
  int y;
};

struct VectorDouble {
  double x;
  double y;
};

template<typename T>
void serialize(std::enable_if<std::is_same<T, VectorInt>::value, T>::type & vect) {
  std::cout << vect.x << std::endl;
}

// maybe do something different with VectorDouble. Overloading would work,
// but I'm curious if it can be made to work with enable_if

}

int main() {
  lib2::VectorInt myvect;
  myvect.x = 2;
  lib1::archive(myvect);
}
#包括
名称空间lib1{
模板
作废档案(T&T)
{
序列化(t);
}
}
名称空间lib2{
结构向量{
int x;
int-y;
};
结构向量双精度{
双x;
双y;
};
模板
void序列化(std::enable_if::type&vect){

std::cout在您的示例中有两个独立的事情:有(函数)模板参数推断,还有参数相关查找(ADL)。如果您开始尝试显式指定模板参数(嘿,是C++),这两者之间的关系会稍微复杂一些,您可以在这里阅读更多内容:(在注释部分)

<>这是说,一般来说,C++中通常允许函数模板推导它们的参数而不是显式指定它们,这正是你在这里试图做的,所以一切都很好。 当您这样做时:

namespace lib1 {
  template <typename T>
  void archive(T & t)
  {
    serialize(t);
  }
}

你没有明确地指定模板参数,所以必须推导出来。但是这里给出的表单不允许演绎:参见非推导上下文,第一个例子。为了更好地理解为什么,请考虑编译器要做的事情:你正在通过<代码>向量> <代码>,并要求编译器找到<代码>

使得
std::enable_if::type>
恰好是
vectorit
。这似乎是合理的,因为从直觉上看
enable_if
只是标识运算符(对于类型)如果第一个参数是真的。但是编译器没有关于
enable\u if
的专门知识。这相当于说:查找
T
,这样
Foo::type
就是
Bar
。编译器无法做到这一点,只能为每个T实例化
Foo
,这是不可能的

我们希望使用enable_if,但不是以禁用扣除的方式。使用
enable_if
的最佳方式通常是在默认模板参数中:

template<typename T, typename U = typename std::enable_if<std::is_same<T, VectorInt>::value>::type >
void serialize(T& vect) {
  std::cout << vect.x << std::endl;
}
模板
无效序列化(T&vect){

std::cout
T
是不可推断的,也不是为
serialize
提供的。您想要什么?您的主要函数中没有什么?vector?我想在这种情况下您需要更改签名?重载
无效序列化(VectorInt&vect)
似乎更简单。@WhataBeautifulfWorld它是矢量的,抱歉,更改了一些代码,但不是全部!这个答案非常长,谢谢。您关于编译器没有关于
enable\u的专门知识的评论非常有用,如果
的话,还有查找
T
的示例,例如
Foo::type
Bar
template<typename T, typename U = typename std::enable_if<std::is_same<T, VectorInt>::value>::type >
void serialize(T& vect) {
  std::cout << vect.x << std::endl;
}