以下問題是從更大的代碼中壓縮的。因此,某些表達式似乎是過度殺傷或不必要的,但對原始代碼至關重要。編譯時依賴於編譯器和優化標誌的模板和constexpr扣除
考慮有一個結構,其中包含編譯時間常數和一個簡單的容器類:
template<typename T> struct CONST
{
static constexpr T ONE()
{
return static_cast<T>(1);
}
};
template<typename T> class Container
{
public:
using value_type = T;
T value;
};
現在具有模板功能,即具有類型提供「專業化」 value_type
:
template<typename T> void doSomething(const typename T::value_type& rhs)
{}
現在我想,這應該工作:
template<typename T> class Tester
{
public:
static constexpr T ONE = CONST<T>::ONE();
void test()
{
doSomething<Container<T>>(ONE);
}
};
有趣的一點是,編譯器不會抱怨Tester<T>::ONE
的定義,但它的用法。此外,如果我在函數調用中使用CONST<T>::ONE()
或者甚至static_cast<T>(ONE)
而不是ONE
,它並不會抱怨。但是,兩者都應在編譯時知道,因此可用。 所以我的第一個問題是:編譯器在這種情況下,它在哪裏工作,甚至在編譯時進行計算?
我用g++-5
,g++-6
和使用-std=c++14
標誌的clang-3.8
編譯器檢查了它。他們都抱怨
undefined reference to `Tester<int>::ONE'
雖然所有使用的功能,據我所知,在標準,因此應該支持。有趣的是,只要我添加優化標記O1
,O2
或O3
,編譯就會成功。所以我的第二個問題是:如果優化標誌處於活動狀態,是否有編譯器只進行編譯時計算的策略?我會期望至少東西,這是宣佈爲編譯時間常數總是演繹!
我的問題的最後部分涵蓋了NVIDIA nvcc
編譯器(版本8.0)。由於我只能通過-std=c++11
,它可能是一些功能通常不包括在內。但是,使用上面的主機編譯器之一,它會抱怨
error: identifier "Tester<int> ::ONE" is undefined in device code
即使通過優化標誌!這顯然是與上面相同的問題,但上述問題更具有學術性(因爲我可以簡單地使用優化標記來擺脫問題),但這真的是一個問題(關於我不知道的事實,當我使用上面提到的解決方法時,在編譯時做了什麼 - 這也是醜陋的)。所以我的第三個問題是:在設備代碼中是否還有一種使用優化的方法?
下面的代碼是純主機的MWE,也爲NVCC編譯:提前
#include <iostream>
#include <cstdlib>
#ifdef __CUDACC__
#define HD __host__ __device__
#else
#define HD
#endif
template<typename T> struct CONST
{
HD static constexpr T ONE()
{
return static_cast<T>(1);
}
};
template<typename T> class Container
{
public:
using value_type = T;
T value;
};
template<typename T> HD void doSomething(const typename T::value_type& rhs) {}
template<typename T> class Tester
{
public:
static constexpr T ONE = CONST<T>::ONE();
HD void test()
{
doSomething<Container<T>>(ONE);
// doSomething<Container<T>>(static_cast<T>(ONE));
// doSomething<Container<T>>(CONST<T>::ONE());
}
};
int main()
{
using t = int;
Tester<t> tester;
tester.test();
return EXIT_SUCCESS;
}
謝謝!
關於你問題的第一部分看http://stackoverflow.com/questions/8452952/c-linker-error-with-class-static-constexpr –