Prenez le code suivant:Quelle est la bonne utilisation d'un foncteur standard constexpr?
#include <iostream>
#include <functional>
template <template<typename> class Op>
auto applyOp(const uint8_t lhs, const uint8_t rhs) {
constexpr Op<uint8_t> op;
return op(lhs, rhs);
}
int main() {
std::cout << +applyOp<std::bit_and>(19, 180) << std::endl;
}
Lorsque vous utilisez g++
, cette compile, et fonctionne très bien. Cependant clang++
donne une erreur:
test.cpp:5:27: error: default initialization of an object of const type 'const bit_and<uint8_t>' (aka 'const bit_and<unsigned char>') without a user-provided default constructor
constexpr Op<uint8_t> op;
^
{}
test.cpp:11:19: note: in instantiation of function template specialization 'applyOp<std::bit_and>' requested here
std::cout << +applyOp<std::bit_and>(19, 180) << std::endl;
^
1 error generated.
Je pris un coup d'oeil au code source pour BIT_AND:
// Copyright (C) 2001-2016 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.
// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
/*
*
* Copyright (c) 1994
* Hewlett-Packard Company
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Hewlett-Packard Company makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*
*
* Copyright (c) 1996-1998
* Silicon Graphics Computer Systems, Inc.
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
[ ... content omitted ... ]
template<typename _Arg1, typename _Arg2, typename _Result>
struct binary_function
{
/// @c first_argument_type is the type of the first argument
typedef _Arg1 first_argument_type;
/// @c second_argument_type is the type of the second argument
typedef _Arg2 second_argument_type;
/// @c result_type is the return type
typedef _Result result_type;
};
[ ... content omitted ... ]
#if __cplusplus > 201103L
template<typename _Tp = void>
struct bit_and;
[ ... content omitted ... ]
#endif
[ ... content omitted ... ]
// _GLIBCXX_RESOLVE_LIB_DEFECTS
// DR 660. Missing Bitwise Operations.
template<typename _Tp>
struct bit_and : public binary_function<_Tp, _Tp, _Tp>
{
_GLIBCXX14_CONSTEXPR
_Tp
operator()(const _Tp& __x, const _Tp& __y) const
{ return __x & __y; }
};
[ ... content omitted ... ]
Pour ce que je peux dire, un constructeur par défaut doit être généré ici. Il est intéressant de noter que le message d'erreur demande spécifiquement un "constructeur par défaut fourni par l'utilisateur" plutôt qu'un simple "constructeur par défaut".
Modification de la ligne incriminée à utiliser l'initialisation uniforme conduit le code à travailler avec les deux compilateurs:
- constexpr Op<uint8_t> op;
+ constexpr Op<uint8_t> op { };
Ma question est, est clang++
correcte pour exiger ces accolades supplémentaires, ou est-g++
raison de ne pas?
Extra info
avec commande g++
Compiler:
g++ test.cpp -Werror -Wall -pedantic -std=c++14
avec commande clang++
Compiler:
clang++ test.cpp -Werror -Wall -pedantic -std=c++14
exécution de la commande d'application:
./a.out
Lieu de bit_and
Définition:
/usr/include/c++/6.2.0/bits/stl_function.h
En ce qui concerne le drapeau possible duplicate, je ne crois pas que ce soit un doublon car cette question demande pourquoi cette règle existe, alors que ma question était plus découvrir certaines la règle en premier lieu et quel compilateur est correct dans son application. De plus, les réponses au duplicata allégué ne répondent pas à ma question.
Fonctionne-t-il avec 'constexpr Op op {};'? –
@DanielJour oui, merci! Question mise à jour – OMGtechy
Copie possible de [Pourquoi C++ nécessite un constructeur par défaut fourni par l'utilisateur pour construire par défaut un objet const?] (Http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided -default-constructor-to-default-construct-a) – Oktalist