From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29321 invoked by alias); 17 Sep 2004 11:41:09 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 29253 invoked from network); 17 Sep 2004 11:41:04 -0000 Received: from unknown (HELO avocet.mail.pas.earthlink.net) (207.217.120.50) by sourceware.org with SMTP; 17 Sep 2004 11:41:04 -0000 Received: from cbl253.pool006.ch001-glendale.dhcp.hs.earthlink.net ([24.41.9.253] helo=[10.0.1.201]) by avocet.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 1C8H6s-0002oT-00 for gcc@gcc.gnu.org; Fri, 17 Sep 2004 04:41:02 -0700 Mime-Version: 1.0 (Apple Message framework v619) Content-Transfer-Encoding: 7bit Message-Id: <72CB8FCC-089E-11D9-B0E1-003065D56982@alum.mit.edu> Content-Type: text/plain; charset=US-ASCII; format=flowed To: gcc@gcc.gnu.org From: Alan Lehotsky Subject: template function specialization trouble - probably a user error, but... Date: Fri, 17 Sep 2004 12:27:00 -0000 X-SW-Source: 2004-09/txt/msg01049.txt.bz2 I'm trying to write a templated function with the following behavior. Given a type T and an integer width, write a function that creates a constant of either type T (for POD T) or of type T::basetype for any aggregate type having a T::basetype that's a POD. The constant is composed of a bitstring of length 'width'. The following works as long as I don't try to handle aggregate types. But SFINAE doesn't stop gcc (2.95.3 or 3.4.2) from complaining about the specialization template<> inline T::basetype MASK(int width) .... producing about 80 lines of errors all told. I've elided some that I'm pretty sure are irrelevant. How can I make the return type of the function do the right thing here? ================================================= struct composite { int i; typedef int basetype; }; template inline T MASK (int width) { if (width < 0 || width > (sizeof(T)*8)) return T (0); else if (width == (sizeof(T)*8)) return ~T (0); else return T(~((~T(0)) << width)); } // Specialization for composite data types #ifdef BAD template <> inline T::basetype MASK(int width) { return MASK(width); } #endif #include int main () { int svar = -3; std::cout << "MASK(5) = " << (int) MASK(5) << std::endl; std::cout << "MASK(3) = " << (int) MASK(3) << std::endl; std::cout << "MASK(4) = " << (int) MASK(4) << std::endl; std::cout << "MASK(70) = " << MASK(70) << std::endl; std::cout << "MASK(64) = " << MASK(64) << std::endl; #ifdef BAD std::cout << "MASK(7) = " << MASK(7) << std::endl; #endif return 0; } ============================================= /tools/linux/gcc-3.4.2/bin/g++ -o mask mask.cxx -DBAD mask.cxx:18: error: `T' has not been declared mask.cxx:19: error: expected init-declarator before "MASK" mask.cxx:19: error: expected `;' before "MASK" mask.cxx: In function `int main()': ......... mask.cxx: In function `T MASK(int) [with T = composite]': mask.cxx:36: instantiated from here mask.cxx:9: error: no matching function for call to `composite::composite(int)' mask.cxx:2: note: candidates are: composite::composite() mask.cxx:2: note: composite::composite(const composite&) mask.cxx:11: error: no matching function for call to `composite::composite(int)' mask.cxx:2: note: candidates are: composite::composite() mask.cxx:2: note: composite::composite(const composite&) mask.cxx:13: error: no matching function for call to `composite::composite(int)' mask.cxx:2: note: candidates are: composite::composite() mask.cxx:2: note: composite::composite(const composite&) [apl]aluminum$ Alan Lehotsky - apl@carbondesignsystems.com Carbon Design Systems, Inc