Hi, if a private static method is passed as a template argument, the visibility depends whether pointer syntax is used or not.
A simple example (more complex ones in attachment): // ====================================================== #include <iostream> typedef int F(int i); template<F* f> class Class1 { public: Class1() { std::cout << "Class1:" << (*f)(1) << "\n"; // <- the compiler complains here // << f (1) << "\n"; <- this one works! } }; class Class2 { public: Class2() { Class1<&m> a; } private: static int m(int i) { return i + 1; } }; int main() { Class2 c; return 0; } // ====================================================== gives the compiler error: test.cpp: In constructor Class1<f>::Class1() [with int (* f)(int) = Class2::m]: test.cpp:20: instantiated from here test.cpp:24: error: static int Class2::m(int) is private test.cpp:10: error: within this context If (*f)(1) is replaced with f(1) the compiler accepts the code. I examined more variations of this code pattern and have written three test programs with various compiler switches that turn on or off pointer syntax and I also included shell scripts to invoke the compiler with all permutations of the switches, see attachment. Command: CXX=g++-4.4.3 sh classtest01.sh Output: 0 0 0 --> 0 0 0 1 --> 0 0 1 0 --> private 0 1 1 --> private 1 0 0 --> 0 1 0 1 --> 0 1 1 0 --> private 1 1 1 --> private Explanation: In this example there are three compiler switches to turn on of off pointer syntax, the switches are printed at the beginning of the line (e.g. "0 0 0" means: no pointer syntax). After the "-->" the return code of the compiler invocation is printed (0 is ok). If the compiler error message indicates that there is an access problem because the member is private, the word "private" is printed after the "-->". So the first test indicates that there are 4 syntax combinations where the compiler doesn't compile the code. Command: CXX=g++-4.4.3 sh functiontest01.sh Output: 0 0 0 --> 0 0 0 1 --> 0 0 1 0 --> private 0 1 1 --> private 1 0 0 --> 0 1 0 1 --> 0 1 1 0 --> private 1 1 1 --> private Now a more complex example: Command: CXX=g++-4.4.3 sh functiontest02.sh Output: 0 0 0 0 0 --> 0 0 0 0 0 1 --> 0 0 0 0 1 0 --> 0 0 0 0 1 1 --> 0 0 0 1 0 0 --> 1 0 0 1 0 1 --> 1 0 0 1 1 0 --> 1 0 0 1 1 1 --> 1 0 1 0 0 0 --> private 0 1 0 0 1 --> private 0 1 0 1 0 --> private 0 1 0 1 1 --> private 0 1 1 0 0 --> 1 0 1 1 0 1 --> 1 0 1 1 1 0 --> 1 0 1 1 1 1 --> 1 1 0 0 0 0 --> 0 1 0 0 0 1 --> 0 1 0 0 1 0 --> 0 1 0 0 1 1 --> 0 1 0 1 0 0 --> 1 1 0 1 0 1 --> 1 1 0 1 1 0 --> 1 1 0 1 1 1 --> 1 1 1 0 0 0 --> private 1 1 0 0 1 --> private 1 1 0 1 0 --> private 1 1 0 1 1 --> private 1 1 1 0 0 --> 1 1 1 1 0 1 --> 1 1 1 1 1 0 --> 1 1 1 1 1 1 --> 1 Explanation: Returncode 1 indicates another compiler error: functiontest02.cpp: In function void function1(int) [with int (* f)(int) = Class2::m]: functiontest02.cpp:71: instantiated from here functiontest02.cpp:57: error: lvalue required as unary & operand All of the above examples and *all* combinations compile with return code 0 to a correct program with expected bahaviour if one of the following compilers is used: a) Intel: icc (ICC) 11.1 20100203 b) Microsoft: cl 32-bit C/C++ Version 15.00.30729.01 for 80x86 IMHO all of the examples and all combinations are valid C++ code. However I may be wrong ;-) Anyway it seems strange that the access refusal to private methods as template arguments depends whether pointer syntax is used or not. Best regards, Oliver -- Summary: access to private function as template argument depends on pointer syntax Product: gcc Version: 4.4.3 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: oschmidt_do_not_send_email_to_this_address at gmx dot de GCC build triplet: i686-pc-linux-gnu GCC host triplet: i686-pc-linux-gnu GCC target triplet: i686-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43465