2017-03-12 7 views
11

は、次のコードを取る: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; 
} 

g++を使用して、これはコンパイルし、うまく動作します。しかしclang++はエラーを生成:

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. 

だから私は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 ... ] 

を、デフォルトコンストラクタがここで生成されなければなりません。興味深いことに、エラーメッセージは、単に「デフォルトコンストラクタ」ではなく、「ユーザー提供のデフォルトコンストラクタ」を要求します。均一な初期化を使用するように問題のある行を変更する

は、両方のコンパイラで動作するようにコードをリード:

- constexpr Op<uint8_t> op; 
+ constexpr Op<uint8_t> op { }; 

私の質問は、これらの余分な括弧を要求における正しいclang++あり、そうでないかでg++正しいですか?

追加情報g++コマンドでコンパイル

clang++コマンドでコンパイル
g++ test.cpp -Werror -Wall -pedantic -std=c++14 

:アプリケーションのコマンドを実行

clang++ test.cpp -Werror -Wall -pedantic -std=c++14 

定義の

場所:私の質問は、約見つけるの詳細だった一方でpossible duplicateフラグについて

/usr/include/c++/6.2.0/bits/stl_function.h 

は、私は、このルールが存在する理由その質問を求めているので、これが重複しているとは思いません最初の場所のルールとそのコンパイラが正しいかどうかを調べる。さらに、重複していると主張する回答は私の質問には答えません。

+1

'constexpr Op op {};'で動作しますか? –

+0

@DanielJourはい、ありがとう!質問が更新されました。 – OMGtechy

+0

[C++でconstオブジェクトをデフォルトで構築するために、ユーザー提供のデフォルトコンストラクタが必要なのはなぜですか?](http://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided -default-constructor-to-default-construct-a) – Oktalist

答えて

9

[dcl.init]必要という点で、元のC++ 14文言:

したがって

If a program calls for the default-initialization of an object of a const -qualified type T , T shall be a class type with a user-provided default constructor.

、単にデフォルトのコンストラクタを持つことは不十分です。また、ユーザーが提供する必要がありました。 Clangはこのルールを実装しましたが、これにはconstexpr Op<uint8_t> op{};が必要でしたが、gccはそうしませんでした。この場合、デフォルトの初期化が可能です。

この文言はちょうどp0490に改訂されました。遡及C++ 14に適用される新しい文言は、読み:デフォルトことができるように

A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T (not inherited from a base class) or if
— each direct non-variant non-static data member M of T has a default member initializer or, if M is of class type X (or array thereof), X is const-default-constructible,
— if T is a union with at least one non-static data member, exactly one variant member has a default member initializer,
— if T is a not a union, for each anonymous union member with at least one non-static data member (if any), exactly one non-static data member has a default member initializer, and each potentially constructed base class of T is const-default-constructible.

If a program calls for the default-initialization of an object of a const-qualified type T, T shall be a const-default-constructible class type or array thereof.

Op<uint8_t>は、のconstデフォルト-構成可能(それは非静的データメンバを持っていないことをささいな理由で)ですそれを初期化する。さて、C++ 14ができるようになります:

constexpr Op<uint8_t> op; 

が効果的に、我々は(それを許可しない)打ち鳴らすのバグ(デフォルト初期化が可能)gccのバグから行ってきました。

+0

私が理解しているように、C++ 14標準はこの新しい表現を反映するように変更されるか、将来のリリース(C++ 1z)? (私は欠陥プロセスに精通していません) – OMGtechy

+1

@OMGtechy C++ 14は_changed_そうではありませんが、委員会はこれをC++ 14の欠陥と記述しているため、コンパイル時に新しい規則が適用されることがありますC++ 14モード。 – Oktalist

関連する問題