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::coutT
是不可推断的,也不是为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;
}