2016-04-06 5 views
0

ビット単位の操作を行うメソッドでテンプレートクラスを作成していますので、このメソッドが使用されるケースではis_integralの型を制限します。私は簡単な例hereを取り、次のようにビットを変更:テンプレートメンバー関数のタイプを制限するためにtype_traitsを使用する

#include <iostream> 
#include <type_traits> 

template <typename T> 
class A 
{ 
    public: 
    A(); 

    T foo(T i) { 
     static_assert(std::is_integral<T>::value, "Integer required."); 
     return (i & 2); 
    } 

    private: 
    T x; 
}; 

int main() { 
    A<double> a; 
    std::cout << a.foo(3) << std::endl; 

    return 0; 
} 

しかし、コンパイラはstatic_assert()でコンパイルエラーを2私を与える:

static_assert failed "Integer required." 

return (i & 2);時:

invalid operands to binary expression ('double' and 'double') 

マイ質問には、とにかくreturn (i & 2);のエラーが表示される場合は、type_traitsを使用してここでタイプを確認してくださいもっと少なく?そして、コンパイルできないようにする代わりに、実行時にコンソール出力にエラーをスローする方法はありますか?

+0

QtはC++コンパイラではありませんが、あなたはあなたのコンパイラに名前を付ける必要がありますので。 – AnatolyS

+0

'とにかくコンソール出力にエラーがスローされて' static_assert –

+0

@AnatolySの目的を破りますが、Qtは実際にはコンパイラではありません。実際のコンパイラは質問には関係ありません。私はそれを編集し、Qtを削除します。 – SergeyA

答えて

0

コンパイラはできるだけ多くのエラーを報告しようとしています。 static_assertはエラーを報告しますが、別のエラーもあります(&の場合はdouble引数を使用します)。

出力を1つのエラーに制限したい場合は、2つのsfinae対応オーバーロードがあり、もう1つはインテグラル以外のものに対してはstatic_assertで構成する必要があります。

あなたの最後の質問として、static_assertを実行する目的は、でエラーをトリガーすることです。実行時ではなく、です。

+0

最後の質問では、私はそれを知っていました。コンパイラは常にビット単位の操作でエラーを実現するため、実行時にのみエラーをトリガしてスローする方法(もちろん 'static_assert'以外)があるかどうかを尋ねました。 。のように 'Error:at YYY function XXX at – scmg

+0

@scmgのように、なぜこれをやりたいのですか?これは、コンパイル時に100%検出可能なエラーです。実行時にレポートする理由は何ですか?人々はコンパイル時にできるだけ多く報告するためにかなりの努力を費やしています。なぜ反対の方向に進みたいのですか? – SergeyA

1

My question is, if it will show the error at line return (i & 2); anyway, using type_traits to check for type here seems useless?

とにかく後続のコンパイルエラーが発生するのは残念ですが、コンパイルエラーの方が読みやすくなりますか?

  • "整数が必要です。"バイナリ表現(doubledouble)へ
  • 無効なオペランド

私は私が最初のものについて間違って何をしたか知っている - 私はA<double>を持っていますが、foo()は整数が必要です。第二の考えはありません。あなたのクラステンプレートを悪用しているのですか、それともバグがありますか?

And, is there anyway to throw the error to console output when it runs, instead of making it unable to be compiled?

あなたはそれはコンパイルエラーになりたい。コンパイル時にエラーをキャッチするのは、コンパイル時にエラーをキャッチするよりもはるかに優れています。

0

同じことを達成する別の方法があります。あなたは、またはエラーメッセージを好むかもしれないことがあります。

#include <iostream> 
#include <type_traits> 

template <typename T, typename = std::enable_if_t<std::is_integral<T>::value>> 
class A 
{ 
    public: 
    A(); 

    T foo(T i) { 
     return (i & 2); 
    } 

    private: 
    T x; 
}; 

int main() { 
    A<double> a; 
    std::cout << a.foo(3) << std::endl; 

    return 0; 
} 

サンプルエラー:

In file included from /opt/gcc-5.3.0/include/c++/5.3.0/bits/move.h:57:0, 
from /opt/gcc-5.3.0/include/c++/5.3.0/bits/stl_pair.h:59, 
from /opt/gcc-5.3.0/include/c++/5.3.0/bits/stl_algobase.h:64, 
from /opt/gcc-5.3.0/include/c++/5.3.0/bits/char_traits.h:39, 
from /opt/gcc-5.3.0/include/c++/5.3.0/ios:40, 
from /opt/gcc-5.3.0/include/c++/5.3.0/ostream:38, 
from /opt/gcc-5.3.0/include/c++/5.3.0/iostream:39, 
from /tmp/gcc-explorer-compiler11636-75-1ve7gbt/example.cpp:1: 
/opt/gcc-5.3.0/include/c++/5.3.0/type_traits: In substitution of 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = std::integral_constant<bool, false>::value; _Tp = void]': 
19 : required from here 
/opt/gcc-5.3.0/include/c++/5.3.0/type_traits:2388:61: error: no type named 'type' in 'struct std::enable_if<false, void>' 
using enable_if_t = typename enable_if<_Cond, _Tp>::type; 
^ 
/tmp/gcc-explorer-compiler11636-75-1ve7gbt/example.cpp: In function 'int main()': 
19 : error: template argument 2 is invalid 
A<double> a; 
^ 
20 : error: request for member 'foo' in 'a', which is of non-class type 'int' 
std::cout << a.foo(3) << std::endl; 
^ 
Compilation failed