我有一个函数,它将函数指针作为参数,然后用它自己的参数调用该函数:
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> );
*/
使用指针作为模板参数时出现了我的问题。每当我使用指向任何类型的常量数据的指针作为模板参数时,它只有在传递的参数被声明为该类型的非常量数组时才能编译。
char char_array[] = "works";
const char const_char_array[] = "error";
char *char_ptr = "error";
const char *const_char_ptr = "error";
Clang (ver. 3.0-6) 中的相关错误(char_ptr
和的错误const_char_ptr
是相同的):
func_ptr.cpp:29:9: error: no matching function for call to 'foo'
foo( add_strlen<const_char_array> );
^~~
func_ptr.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 )
谁能向我解释这是为什么?在我看来,模板参数S
应该是 type const char*
,这在任何其他情况下意味着我可以传入任何 const 或非 const 指针或类型的数组char
并期望它工作。我希望能够将我的数组声明为const
,因为我什至不想暗示它们应该在运行时进行修改。有没有办法让我的数组保持不变并将它们用作模板参数?
编辑:感谢一些帮助(以及更新版本的 Clang 错误更好),我能够确定提供具有内部链接的模板参数是问题的一部分。通过将上述变量声明为 extern,我可以毫无错误地使用add_strlen<const_char_array>
。我还创建了一个简化的测试用例。它包括在下面:
#include <cstring>
typedef int (*my_func_ptr)( int );
int foo( my_func_ptr f ) {
static int i = 0;
return i = f( i );
}
template<const char* S>
int add_strlen( int i ) {
return i + strlen( S );
}
extern char char_array[];
extern const char const_char_array[];
extern char *char_ptr;
extern const char *const_char_ptr;
char char_array[] = "foo";
const char const_char_array[] = "bar";
// assigning to string literal is deprecated
char *char_ptr = char_array;
const char *const_char_ptr = "baz";
int main(int argc, const char *argv[])
{
foo( add_strlen<char_array> ); // works
foo( add_strlen<const_char_array> ); // works
//foo( add_strlen<char_ptr> ); // doesn't work
//foo( add_strlen<const_char_ptr> ); // doesn't work
return 0;
}