C++ 无法将指向常量数据的指针作为函数模板参数传递

C++ 无法将指向常量数据的指针作为函数模板参数传递,c++,templates,C++,Templates,我有一个函数,它将函数指针作为参数,然后用自己的参数调用该函数: typedef int (*my_func_ptr)( int ); int foo( my_func_ptr f ) { static int i = 0; return i = f( i ); } 有时,我需要将函数传递给foo,这些函数不仅依赖于整数输入,还需要输出结果 int add_strlen( int i, const char* s ) { return i + strlen( s );

我有一个函数,它将函数指针作为参数,然后用自己的参数调用该函数:

typedef int (*my_func_ptr)( int );

int foo( my_func_ptr f ) {
    static int i = 0;
    return i = f( i );
}
有时,我需要将函数传递给
foo
,这些函数不仅依赖于整数输入,还需要输出结果

int add_strlen( int i, const char* s ) {
    return i + strlen( s );
}
我可以重新编写上面的代码来使用
std::function
,然后使用
std::bind
,但我更喜欢在编译时创建这些函数,所以我使用的是模板

template<const char* S>
int add_strlen( int i ) {
    return i + strlen( S );
}

/**
 * Usage:
 * char bar[] = "bar";
 * foo( add_strlen<bar> );
 */
Clang中的相关错误(版本3.0-6)(字符ptr和字符ptr的错误相同):


该错误似乎与您是什么以及您不允许将什么用作非类型模板参数有关,因为他们这样说:

非类型模板参数的语法与以下类型之一的声明相同:

  • 积分或枚举
  • 指向对象的指针或指向函数的指针
  • 对对象的引用或对函数的引用
  • 指向成员的指针
char\u array[]
const\u char\u array[]
在传入时工作的原因是,它们在编译时是常量,并且在程序运行时不会在程序下面更改。可以传入整型,但无法传入指向整型的指针

模板需要一种类型的
const char*
a.k.a
const char[x]
,但它也需要一些永远不会更改的内容,因此指针指向的位置可能永远不会更改。当在编译时传入您的
const\u char\u数组时
将传递一个
char[6]
(“错误”)。位置永远不会改变,内容也永远不会改变。但是,当传入
常量字符\u ptr
时,它会得到一个
常量字符*
,虽然指针本身可能永远不会改变,但它指向的位置完全可能会改变。它本身不是静态的

char *_arr = new char[20];
const char* _ptr_arr = _arr;
我们在此同意,我的
\u ptr\u arr
与您的
const\u char\u ptr
类型完全相同,但存储内容的位置可能在运行时发生变化。在模板中,这是不允许的,因为它可能需要一个全新的模板实例化,并且从创建模板时起是不确定的。字符[6]是静态的,不会更改

foo( add_strlen<_ptr_arr> );
foo(添加strlen);
导致以下编译器错误:

test.cpp:36:5: error: no matching function for call to 'foo'
    foo( add_strlen<_ptr_arr>);
    ^~~
test.cpp:6:5: note: candidate function not viable: no overload of 'add_strlen' matching 'my_func_ptr' (aka 'int (*)(int)') for 1st argument
int foo( my_func_ptr f ) {
    ^
test.cpp:36:5:错误:调用'foo'没有匹配的函数
foo(add_strlen);
^~~
test.cpp:6:5:注意:候选函数不可行:没有重载与第一个参数“my_func_ptr”(又名“int(*)(int)”)匹配的“add_strlen”
int foo(我的功能){
^
这不是很有帮助,我们想弄清楚为什么没有有效的重载,使用函数独立编译代码而不作为函数指针传递,我们得到以下结果:

add_strlen<_ptr_arr>(0);
add_strlen(0);
将导致:

test.cpp:36:5: error: no matching function for call to 'add_strlen'
    add_strlen<_ptr_arr>(0);
    ^~~~~~~~~~~~~~~~~~~~
test.cpp:16:5: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'S'
int add_strlen( int i ) {
    ^
test.cpp:36:5:错误:调用“add\u strlen”时没有匹配函数
添加_strlen(0);
^~~~~~~~~~~~~~~~~~~~
test.cpp:16:5:注意:已忽略候选模板:为模板参数“”显式指定的参数无效
内部添加\u strlen(内部i){
^
所以显式指定的参数是无效的,特别是,我们不能传入指向整数的指针

test.cpp:36:5: error: no matching function for call to 'foo'
    foo( add_strlen<_ptr_arr>);
    ^~~
test.cpp:6:5: note: candidate function not viable: no overload of 'add_strlen' matching 'my_func_ptr' (aka 'int (*)(int)') for 1st argument
int foo( my_func_ptr f ) {
    ^
add_strlen<_ptr_arr>(0);
test.cpp:36:5: error: no matching function for call to 'add_strlen'
    add_strlen<_ptr_arr>(0);
    ^~~~~~~~~~~~~~~~~~~~
test.cpp:16:5: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'S'
int add_strlen( int i ) {
    ^