C++ 模板的类型分组显式实例化
如果我有一个带有重载模板成员函数的模板类(使用SFINAE),如:C++ 模板的类型分组显式实例化,c++,templates,explicit-instantiation,C++,Templates,Explicit Instantiation,如果我有一个带有重载模板成员函数的模板类(使用SFINAE),如: 模板 结构Foo{ Foo(T elem); 模板 auto get()->std::启用\u如果\u t; 模板 auto get()->std::启用\u如果\u t; T元素; }; 现在,在我的CPP文件中,我必须定义并显式实例化: template class Foo<int>; template int Foo<int>::get<int>(); template class F
模板
结构Foo{
Foo(T elem);
模板
auto get()->std::启用\u如果\u t;
模板
auto get()->std::启用\u如果\u t;
T元素;
};
现在,在我的CPP文件中,我必须定义并显式实例化:
template class Foo<int>;
template int Foo<int>::get<int>();
template class Foo<bool>;
template bool Foo<bool>::get<bool>();
// For all types...T, there will be two statements.
模板类Foo;
模板int Foo::get();
模板类Foo;
模板bool Foo::get();
//对于所有类型…T,将有两个语句。
按类型进行分组实例化的可能方法有哪些?类似于:
GroupedFooInit<int>(); // does both Foo<int> and Foo<int>::get<int>
GroupedFooInit<bool>(); // similar
.. and so on.
GroupedFooInit();//Foo和Foo::是否都可以
GroupedFooInit();//类似的
.. 等等
考虑到我必须使用C++14,我可以想出两种变通方法,但我不想这样做:1. <代码>宏:可能,但希望极力避免。
2. <代码>标题中的定义,无需显式实例化:可能,但我正在处理一个庞大的repo,其中我处理的文件几乎无处不在-因此,如果我通过这种方式进行细微更改,我的构建时间将非常长
您可以通过添加图层来解决此问题:
template <typename T>
struct Foo{
Foo(T elem);
T elem_;
T get(){
return do_get<T>();
}
private:
template <typename U = T>
auto do_get() -> std::enable_if_t<std::is_same<U, int>::value, U>;
template <typename U = T>
auto do_get() -> std::enable_if_t<std::is_same<U, bool>::value, U>;
};
//If definitions for the do_get functions are provided before these
//explicit template instantiation definitions, the compiler will certainly
//inline those definitions.
template class Foo<int>;
template class Foo<bool>;
模板
结构Foo{
Foo(T elem);
T元素;
不明白{
返回do_get();
}
私人:
模板
auto do_get()->std::启用;
模板
auto do_get()->std::启用;
};
//如果之前提供了do_get函数的定义
//显式模板实例化定义,编译器肯定会
//内联这些定义。
模板类Foo;
模板类Foo;
因此,您在这里使用SFINAE只是为了根据T
单独在两个重载中选择一个?您不能在唯一的get
函数体中使用if constexpr
吗?@StoryTeller yes-Edit:如果可以对N个不同的overloads@Oliv卡在C++14的土地上,在问题MMM中添加澄清。我的建议是根本不走SFINAE路线。然后你可以得到你想要的,简单和外部定义。但如果您在T
上的条件与本例中的条件不完全相同,则可能不合适,
template <typename T>
struct Foo{
Foo(T elem);
T elem_;
T get(){
return do_get<T>();
}
private:
template <typename U = T>
auto do_get() -> std::enable_if_t<std::is_same<U, int>::value, U>;
template <typename U = T>
auto do_get() -> std::enable_if_t<std::is_same<U, bool>::value, U>;
};
//If definitions for the do_get functions are provided before these
//explicit template instantiation definitions, the compiler will certainly
//inline those definitions.
template class Foo<int>;
template class Foo<bool>;