我看到了可能的实现,std::remove_reference
如下所示
template< class T > struct remove_reference {typedef T type;};
template< class T > struct remove_reference<T&> {typedef T type;};
template< class T > struct remove_reference<T&&> {typedef T type;};
Run Code Online (Sandbox Code Playgroud)
为什么有专业化lvalue
和rvalue reference
?一般模板本身是否足够并删除引用?我在这里很困惑,因为在T&
或者T&&
专业化中如果我尝试使用::type
我还应该得到T&
或T&&
分别对吗?
你能解释一下,为什么我们投入remove_reference<t>::type&&
移动?(是因为参数被命名所以它将被视为移动函数内的左值?).
另外,你能指出一种方法,我可以找到并打印出这种类型的东西吗?例如,如果它的rvalue
类型,int
那么我应该能够打印出来的那个int&&
?(我一直在用std::is_same
手动检查.)
感谢您的时间.
给定一个模板参数的数值常量,是否有一种直接的方法来定义C++模板类的部分特化?我正在尝试为特定类型的模板组合创建特殊构造函数:
template <typename A, size_t B> class Example
{
public:
Example() { };
A value[B];
};
template <typename A, 2> class Example
{
public:
Example(b1, b2) { value[0] = b1; value[1] = b2; };
};
Run Code Online (Sandbox Code Playgroud)
此示例将无法编译,Expected identifier before numeric constant
在第二个定义中返回错误.
我已经看过这里和其他地方的一些例子,但大多数似乎都围绕着一个类型而不是一个常量.
编辑:
寻找一种编写有条件使用的构造函数的方法,其功能如下:
template <typename A, size_t B> class Example
{
public:
// Default constructor
Example() { };
// Specialized constructor for two values
Example<A,2>(A b1, A b2) { value[0] = b1; value[1] = b2; };
A foo() …
Run Code Online (Sandbox Code Playgroud) 以下函数模板中第二个括号<>的原因是什么:
template<> void doh::operator()<>(int i)
Run Code Online (Sandbox Code Playgroud)
这出现在SO问题中,有人提出之后有一些括号丢失operator()
,但是我找不到解释.
如果它是表单的类型特化(完全特化),我理解其含义:
template< typename A > struct AA {};
template<> struct AA<int> {}; // hope this is correct, specialize for int
Run Code Online (Sandbox Code Playgroud)
但是对于功能模板:
template< typename A > void f( A );
template< typename A > void f( A* ); // overload of the above for pointers
template<> void f<int>(int); // full specialization for int
Run Code Online (Sandbox Code Playgroud)
这适合这种情况?:
template<> void doh::operator()<>(bool b) {}
Run Code Online (Sandbox Code Playgroud)
示例代码似乎有效并且没有给出任何警告/错误(使用gcc 3.3.3):
#include <iostream>
using namespace std;
struct doh
{
void operator()(bool …
Run Code Online (Sandbox Code Playgroud) 摘要
有没有办法在模板化类型上调用类方法,该模板可能是指针或引用而不知道哪个而不是获取编译器/链接器错误?
细节
我有一个模板化的QuadTree实现,可以采用以下任何非平凡的用户定义类型:
//Abstract Base Class
a2de::Shape
//Derived Classes
a2de::Point
a2de::Line
a2de::Rectangle
a2de::Circle
a2de::Ellipse
a2de::Triangle
a2de::Arc
a2de::Spline
a2de::Sector
a2de::Polygon
Run Code Online (Sandbox Code Playgroud)
但它们可能是指针或引用,因为它们都是从a2de :: Shape派生的.因此专业化被声明为:
template class QuadTree<a2de::Shape&>;
//...similar for all derived types as references.
template class QuadTree<a2de::Shape*>;
//...similar for all derived types as pointers
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是当间接(或缺少)未知时调用类方法的能力,并且由于模板,生成了两组代码:
template<typename T>
bool QuadTree<T>::Add(T& elem) {
//When elem of type T is expecting a pointer here
//-> notation fails to compile where T is a reference i.e.:
//template class QuadTree<a2de::Shape&>
//with "pointer to reference is illegal" …
Run Code Online (Sandbox Code Playgroud) 什么是专门用于模板类中的模板函数的C++语法?例如,考虑我有以下两个类及其用法.我希望能够为不同类型提供方法X :: getAThing()的专门实现.例如:int,std :: string,任意指针或类等.
template <class c1> class X {
public:
template<typename returnT> returnT getAThing(std::string param);
static std::string getName();
private:
c1 theData;
};
// This works ok...
template <class c1> std::string X<c1>::getName() {
return c1::getName();
}
// This blows up with the error:
// error: prototype for 'int X<c1>::getAThing(std::string)' does not match any in class 'X<c1>'
template <class c1> template <typename returnT> int X<c1>::getAThing(std::string param) {
return getIntThing(param); // Some function that crunches on param and returns an int. …
Run Code Online (Sandbox Code Playgroud) 我碰到一个C++之间不一致gcc
(版本4.8.1
,4.8.2
)和clang
(版本3.3
,3.4
).我想知道哪一个是正确的.这是程序:
template < typename T > struct Result {};
template < typename T > struct Empty {};
template < typename T >
struct Bad_Type_Fcn {
typedef typename Empty< T >::type type;
};
template < typename T >
Result< T >
f( const T& ) {
return Result< T >();
}
template< class U >
Result< typename Bad_Type_Fcn< U >::type >
f( const U&, int ) {
return Result< …
Run Code Online (Sandbox Code Playgroud) 根据https://en.cppreference.com/,std::vector<bool>
具有类模板专业化,而std::array<bool, N>
没有。不提供的原因有哪些?
c++ stdvector template-specialization class-template stdarray
来自cppreference.com的报价:
添加模板特化
允许为任何标准库类添加模板特化(从C++ 20开始)| 模板到命名空间std只有当声明依赖于至少一个程序定义的类型并且特化满足原始模板的所有要求时,除非禁止这样的特化.
是否意味着,从C++ 20开始,将std
不再允许将函数模板的特化添加到用户定义类型的命名空间中?如果是这样,它意味着许多现有代码可能会破坏,不是吗?(在我看来,这是一种"激进"的改变.)此外,它会向这些代码注入未定义的行为,这不会触发编译错误(警告有希望).
适用于类的语法不适用于概念:
template <class Type>
concept C = requires(Type t) {
// ...
};
template <class Type>
concept C<Type*> = requires(Type t) {
// ...
};
Run Code Online (Sandbox Code Playgroud)
MSVC 对于“专业化”行的说法是:error C7606: 'C': concept cannot be explicitly instantiated, explicitly specialized or partially specialized
。
为什么概念不能专门化?有理论上的原因吗?
模板特化不考虑继承层次结构.例如,如果我专门Base
化模板并将其实例化Derived
,则不会选择特化(参见下面的代码(1)).
这可能是一个主要障碍,因为它有时会导致违反Liskov替代原则.例如,在工作时这个问题,我发现我不能使用Boost.Range算法具有std::sub_match
虽然我可以用std::pair
.由于sub_match
公开继承pair
,常识会指示我可以替换使用的sub_match
所有地方pair
,但由于使用模板专门化的特征类而失败.
我们可以通过使用部分模板特化enable_if
和is_base_of
(见代码(2))来克服这个问题.我是否总是喜欢这种解决方案而不是完全专业化,特别是在编写库代码时?我监督这种方法有什么缺点吗?这是您经常使用或经常使用的做法吗?
示例代码
(1)
#include <iostream>
struct Base {};
struct Derived : public Base {};
template < typename T >
struct Foo
{
static void f() { std::cout << "Default" << std::endl; }
};
template <>
struct Foo< Base >
{
static void f() { std::cout << "Base" << std::endl; }
};
int main()
{
Foo<Derived>::f(); // …
Run Code Online (Sandbox Code Playgroud)