c++ - 概念检查器无法在 gcc 上编译,因为它是 'has no linkage'

标签 c++ c++11 gcc c++-concepts

我创建了一个基于 this question 的概念检查类其目的是确保给定类具有名为 baseUnitConversionFactor 的静态成员函数。该类编译并适用于 msvc2013,但它不会在 gcc 4.9.2 上编译(使用 -std=c++14)并出现错误:

error: ‘{anonymous}::UnitsTest_conceptChecker_Test::TestBody()::validUnit::baseUnitConversionFactor’ is not a valid template argument for type ‘double (*)()’ because ‘static double {anonymous}::UnitsTest_conceptChecker_Test::TestBody()::validUnit::baseUnitConversionFactor()’ has no linkage

static std::true_type test(tester<&U::baseUnitConversionFactor>*);

我真的不知道那是什么意思,而且我更熟悉在 Visual Studio (显然)更宽松的环境中编写模板。谁能帮我弄清楚我需要做什么来解决这个问题?

概念检查类

template <typename T>
struct has_baseUnitConversionFactor
{
    template<double(*)()> struct tester;

    template<typename U>
    static std::true_type test(tester<&U::baseUnitConversionFactor>*);
    template<typename U>
    static std::false_type test(...);

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

我认为导致错误的测试

TEST_F(UnitsTest, conceptChecker)
{
    struct validUnit
    {
        static inline double baseUnitConversionFactor() { return 0.0; }
        typedef void unit_category;
        typedef void base_unit_type;
    };

    EXPECT_TRUE(has_baseUnitConversionFactor<validUnit>::value);
}

最佳答案

在 C++11 和 C++14 中,指针/引用模板参数必须引用具有链接的实体(在 C++03 中,它们仅限于具有外部链接的实体)。本地类没有链接,它的成员函数也没有。

此限制已在 C++17 中被 N4268 移除,并且 GCC trunk 声称已经实现了该论文,但显然不是链接部分。

回避这个问题不需要使用 &U::baseUnitConversionFactor 作为模板非类型参数。令人高兴的是,测试表达式 T::baseUnitConversionFactor() 是否有效并准确返回 double 的一种更简单的方法是:

template <typename T, class=double>
struct has_baseUnitConversionFactor : std::false_type { };

template <typename T>
struct has_baseUnitConversionFactor<T, decltype(T::baseUnitConversionFactor())>
         : std::true_type { };

这确实取决于表达式 SFINAE(但是,原始表达式也是如此),所以我不确定它是否适用于 MSVC 2013。

要进行更一般的检查,您可能需要查看 std::experimental::is_detected_convertible .该 cppreference 页面有一个引用实现。

关于c++ - 概念检查器无法在 gcc 上编译,因为它是 'has no linkage',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34501232/

相关文章:

c++ - 如何有效地从 forward_list 中删除一个元素?

C++编译错误?

C++私有(private)多态实现设计

c++ - 与 using 声明冲突的重载

编译gcc错误 undefined reference `aes256_init'

c++ - 如何正确引用匿名命名空间中的函数

c++ - 从 std::map 派生的类不能在 Visual C++ 上编译(但可以在 gcc 和 clang 上编译)

c++ - CImageList 和 CComboBoxEx 限制为 16 个透明图标

c++ - C++11 中的生产者-消费者

c++ - 在 OpenGl 中读取 TGA 文件以创建 3d use