precios libro electrónico electronico electronic ebooks ebook definicion books c++ c++11 clang language-lawyer

libro - ¿Es esto válido C++ 11?



libro electronico (1)

Creo que esto es un error clang. Desde [temp.param], tenemos:

Si una declaración de plantilla de función amiga especifica un argumento-plantilla predeterminado, esa declaración será una definición y será la única declaración de la plantilla de función en la unidad de traducción.

El conjunto de argumentos de plantilla predeterminados disponibles para su uso se obtiene combinando los argumentos predeterminados de todas las declaraciones anteriores de la plantilla de la misma manera que los argumentos de función predeterminados son (8.3.6).

El último punto significa que podemos escribir:

template <typename T, typename U=int> void h(); template <typename T, typename U> void h() { } h<int>();

Y este es un código perfectamente bien formado que clang compila. No podemos especificar el argumento-plantilla predeterminado para g función de la regla citada, ya que g se declaró anteriormente, pero al no especificarlo, debe seguir estando Defaulted disponible para su uso como void través del paso de combinación. Si el argumento predeterminado está disponible, la búsqueda debería poder encontrar la g que queremos.

Una solución alternativa sería simplemente un amigo de la especialización que nos importa:

friend bool g<>(MyClass value);

Tengo el siguiente código que compila bajo g ++, pero no con clang.

Clang compilará el código si se modifica de varias maneras menores, como fusionar las 2 declaraciones de espacio de nombres.

// The problem disappears without namespaces. namespace Root { // The problem disappears if ''g'' is in the global namespace, and we change // the friend declaration to ''::g'' // The problem disappears if ''g'' has void return type. // The problem disappears if we get rid of the ''Value'' template argument // and the ''value'' parameter. template<typename Value, typename Defaulted = void> bool g(Value value); // The problem disappears if MyClass is not a template. template<typename ClassValue> class MyClass { private: template<typename Value, typename Defaulted> friend bool g(Value value); }; } // The problem disappears if we declare the Root namespace in a single block // containing ''g'', ''MyClass'' and ''f''. // The problem remains if we declare f in the global namespace and reference // Root::g. namespace Root { void f() { MyClass<int> value; g(value); } }

Para compilar con clang:

clang -fsyntax-only -std=c++11 testcase.cpp

Para compilar con g ++:

g++ -fsyntax-only -std=c++11 testcase.cpp

Las versiones son g ++ 4.9.2, clang 3.6.0, ambas en Ubuntu Core 15.04.

Clang da el mensaje de error:

testcase.cpp:24:9: error: no matching function for call to ''g'' g(value); ^ testcase.cpp:14:21: note: candidate template ignored: couldn''t infer template argument ''Defaulted'' friend bool g(Value value); ^ 1 error generated.