无限模板递归,因为仅使用gcc

时间:2019-03-13 14:49:17

标签: c++ templates gcc sfinae enable-if

我正在研究词汇连铸机。请参见下面的代码的简化,有问题的部分。该代码可使用clang和msvc进行编译,但无法使用gcc进行编译。看来,在lexicalCast的std::enable_if的第一个参数中,gcc试图在评估布尔表达式的所有操作数之前先对其求值,而clang和msvc进行优化,如果{{1则忽略LexicalCastable<>:: value的求值}}表达式失败。 我的问题是:

  • 标准是否指定了哪种行为是正确的?
  • 我该如何解决这个问题以便能够使用GCC编译此代码?

代码:

std::is_same

gcc错误:

#include <type_traits>
#include <string>

template<typename From, typename To>
class LexicalCastable;

template<typename To, typename From> typename
    std::enable_if<
           !std::is_same<std::string, To>::value
        && !std::is_same<std::string, From>::value
        && LexicalCastable<From, std::string>::value
        && LexicalCastable<std::string, To>::value,
To>::type lexicalCast(const From &from) {
    return lexicalCast<To>(lexicalCast<std::string>(from));
}

template<typename From, typename To>
class LexicalCastable
{
    template<typename TT>
    static auto test(int)
        -> decltype(lexicalCast<TT>(std::declval<From>()), std::true_type{});

    template<typename>
    static auto test(...)->std::false_type;

public:
    static const bool value = decltype(test<To>(0))::value;
};

static_assert(!LexicalCastable<std::string, std::string>::value, "");

1 个答案:

答案 0 :(得分:3)

  

我该如何解决该问题以便能够使用GCC编译此代码

您可以使用std::conjunction(C ++ 17)来确保短路

template <typename To, typename From>
typename std::enable_if<
    std::conjunction<
           std::negation<std::is_same<std::string, To>>,
           std::negation<std::is_same<std::string, From>>,
           LexicalCastable<From, std::string>
           LexicalCastable<std::string, To>>::value,
    To>::type
lexicalCast(const From &from)
{
    return lexicalCast<To>(lexicalCast<std::string>(from));
}