简体   繁体   English

指针的C ++模板专业化?

[英]C++ template specialization for pointer?

I read book < C++ Templates - the Complete Guide > and learned template specialization for pointer. 我读了书<C ++模板 - 完整指南>和学习指针的模板专业化。 (maybe I misunderstand this part of the book) (也许我误解了这本书的这一部分)

(1) Here's my simple template: (1)这是我的简单模板:

#include <iostream>

template<typename T>
void Function(const T& a)
{
    std::cout << "Function<T>: " << a << std::endl;
}

template<typename T>
void Function<T*>(const T* a)
{
    std::cout << "Function<T*>: " << a << std::endl;
}

int main(void)
{
    Function(1);
    Function(1.2);
    Function("hello");
    Function((void*)0x25);

    return 0;
}

I use ubuntu16.04 x64, g++ 5.3, the compiler report: 我使用ubuntu16.04 x64,g ++ 5.3,编译器报告:

$ g++ main.cpp -o main.exe 
main.cpp:10:29: error: non-type partial specialization ‘Function<T*>’ is not allowed
 void Function<T*>(const T* a)

(2) but this code is correct: (2)但这段代码是正确的:

#include <iostream>

template<typename T>
void Function(const T& a)
{
    std::cout << "Function<T>: " << a << std::endl;
}

int main(void)
{
    Function(1);
    Function(1.2);
    Function("hello");
    Function((void*)0x25);

    return 0;
}

result shows: 结果显示:

$ g++ main.cpp -o main.exe
$ ./main.exe 
Function<T>: 1
Function<T>: 1.2
Function<T>: hello
Function<T>: 0x25

My question is: Is the book about pointer specialization is wrong ? 我的问题是:关于指针专业化的书是错的吗? Or I mis understand the meaning of this part in the book ? 或者我误解了书中这一部分的含义? Or something else ? 或者是其他东西 ?

Update about pointer specialization in class. 关于类中指针特化的更新。

(3) template class with pointer specialization: (3)带指针特化的模板类:

#include <iostream>

template<typename T>
struct Base {
    T member;

    Base(const T& a)
        : member(a)
    {
    }

    void hello()
    {
        std::cout << member << std::endl;
    }
};

template<typename T>
struct Base<T*> {
    T* member;

    Base(T* a)
        : member(a)
    {
    }

    void hello()
    {
        std::cout << member << std::endl;
    }
};

int main(void)
{
    Base<int> b1(12);
    Base<double> b2(2.4);
    Base<char*> b3("hello");
    Base<void*> b4((void*)0x25);

    b1.hello();
    b2.hello();
    b3.hello();
    b4.hello();

    return 0;
}

this code is correct with one warning: 这个代码是正确的,有一个警告:

$ g++ main.cpp -o main.exe 
main.cpp: In function ‘int main()’:
main.cpp:37:27: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
     Base<char*> b3("hello");
                           ^
$ ./main.exe 
12
2.4
hello
0x25

(4) template class without pointer specialization: (4)没有指针专门化的模板类:

#include <iostream>

template<typename T>
struct Base {
    T member;

    Base(const T& a)
        : member(a)
    {
    }

    void hello()
    {
        std::cout << member << std::endl;
    }
};

int main(void)
{
    Base<int> b1(12);
    Base<double> b2(2.4);
    Base<char*> b3("hello");
    Base<void*> b4((void*)0x25);

    b1.hello();
    b2.hello();
    b3.hello();
    b4.hello();

    return 0;
}

result is the same: 结果是一样的:

$ g++ main.cpp -o main.exe
main.cpp: In function ‘int main()’:
main.cpp:39:27: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
     Base<char*> b3("hello");
                           ^
$ ./main.exe 
12
2.4
hello
0x25

Does this means pointer specialization is needless ? 这是否意味着指针专业化是不必要的? Or maybe this feature behave differently on different compiler ? 或者这个功能在不同的编译器上表现不同?

as you've been already told, partial specialization of function templates are not allowed. 正如您已经被告知的那样,不允许对函数模板进行部分特化。 You can use std::enable_if for this: 您可以使用std::enable_if

template <typename T, typename std::enable_if_t<!std::is_pointer<T>::value>* = 0>
void func(T val) { std::cout << val << std::endl; }

template <typename T, typename std::enable_if_t<std::is_pointer<T>::value>* = 0>
void func(T val) { func(*val); }

If you are looking for simpler syntax, wait for concepts 如果您正在寻找更简单的语法,请等待概念

The error message told you what is wrong: 错误消息告诉您错误:

 non-type partial specialization 'Function<T*>' is not allowed 

You can only partially specialize types (classes). 您只能部分地专门化类型(类)。 You've tried to partially specialize a function. 你试图部分专门化一个功能。 Functions are not types; 功能不是类型; you can only fully specialize them. 你只能完全专注他们。

Two problems: 两个问题:

  1. You are not allowed to partially specialise a function. 您不能部分专门化功能。

  2. The behaviour of (void*)0x25 is undefined . (void*)0x25的行为未定义 With the exception of nullptr , you are not allowed to set a pointer to memory you don't own, with the exception of one past the final element of an array and one past the address of a scalar. 除了nullptr ,不允许设置指向您不拥有的内存的指针,除了一个超过数组的最后一个元素和一个超过标量地址的内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM